cloudflare / doca

A CLI tool that scaffolds API documentation based on JSON HyperSchemas.
BSD 3-Clause "New" or "Revised" License
228 stars 36 forks source link

How to add a dependancy to a theme? #39

Closed Relequestual closed 7 years ago

Relequestual commented 7 years ago

I've started trying to work on a theme.

I checked out the doca theme at the bootstrap commit, as it will allow us to apply our styling and colours over the top of bootstrap like the rest of our application.

I wanted to update the version of bootstrap, and remove the use of using a cdn in favour of bundling the bootstrap css in with the rest of the minified file.

I added bootstrap as a dependancy of the new theme, however it seems that I can't actually add bootstrap to my theme from node_modules, as the theme doesn't have a webpack step.

I tried to add the bootstrap css as per example shown at https://github.com/theodybrothers/webpack-bootstrap, however of course it does not work because bootstrap is a dependancy of the theme and not of doca itself.

It seems the only way this would work would be if I were to copy the css required to the styles folder for the theme as part of the build process. This seems somewhat sub-optimal to me.

Am I missing something really obivous here? I'm still new to using node and webpack.


I realise I could just change the version number in the existing cdn URL, but what if I want to add other dependancies? I'm looking at adding a few via bower, but then wanting to use bower components in a webpack setup would create the same disconntion problem, where webpack is run at the doca level and only files in the style folder of the theme are added to the end result.

If I'm totally getting the wrong idea here, please do say. I've spent the good part of a day trying to figure this out and I'm a tad demorilised.

tajo commented 7 years ago

Ok, this is a bit tricky. You can't simply import (require) css files into your theme since the theme itself lives in node_modules and it is not the part of main application. Btw, this CSS importing is pretty special thing, known as CSS Modules, and its Webpack specific (it wouldn't work with different bundlers). But Webpack lives in your main application and can handle these imports only if they originate from the main application. It ignores them in node_modules. On the other hand, plain JS imports are fine, so you can have stuff like:

import React from 'react';

in your theme (node_modules). So your node_modules needs to be just plain JS. Webpack will not apply its loaders on them. That's why the theme runs the code through babel before being published.

How to solve your problem? There are three options. If you don't want to just link the CDN, the best thing is to add ./styles/main.less or ./styles/main.scss or ./styles/main.css into your theme as a entry point for all styling. In case of less and scss you can use the standard less/scss import syntax (you should probably put these imported files outside of ./styles). Doca is automagically trying to find and load these styles through dynamic requires.

Also, since you have access to the head node you could use <style></style>.

Relequestual commented 7 years ago

Right. OK I think I almost worked that out, but wasn't quite clear if it was the expected way to do it. I noticed the automagic line... What happens with reqCSS? (Documentation is a great skill to learn btw ;) )

I've tried to have several css files in the styles directory, and it only picks up 2 out of 3, which is really weird. If I only include one, it always picks up that one, so it's not something funny going on with my npm link process. Any ideas on this one?

I THOUGHT I could try and debug src/client/main.js, but I can't for the life of me figure out how to output / debug the webpack build process. I've given it a good 3 or so hours today trying to work this out...

I could, as you suggested, import other files into a main file and have the other files outside of the styles folder, but give it looks like you suggested, and the magic line suggests, that it should pick up all css files in that location, it feels more reasonable to keep them seperate for my use case.

tajo commented 7 years ago

This is a darker side of webpack - complex and not well understood. There is some legacy documentation about it.

I'm not sure why it doesn't load and extract all files. We've migrated to webpack 2 since then, it is using a beta extract css plugin now... I'm surprised that it even works. Anyway, it always makes sense to have a single entry point importing other stylesheets since the order matters (unless you are using something like BEM). So I recommend this:

import other files into a main file and have the other files outside of the styles folder

We could look more into this in the future. Or just simply require ./main.{less|scss|css} and tell devs that it is expected to have just one single file to avoid confusion.

Relequestual commented 7 years ago

Thanks @tajo, I'll do that for now till it's something you can find to investigate. Would you like me to open a new issue for not loading all the files?

Yeah, I did find that documentation, and plenty of examples, but nothing that satisfactorily explained to me how it works. I understand reqCSS and keys(), but how exactly is forEach() requiering the stuff from keys? I understand it IS doing that, but where do I find documentation that explains this? =/ OK I think I get it now, thanks. It's just a BIT confusing =/

You're right, css import order is important, so it actually makes more sense to have it only import one file, which imports the other files as needed.

tajo commented 7 years ago

Feel free to open a different issue.