Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage in production and includePaths #69

Open
tmaximini opened this issue Mar 24, 2016 · 11 comments
Open

Usage in production and includePaths #69

tmaximini opened this issue Mar 24, 2016 · 11 comments

Comments

@tmaximini
Copy link

Hey!
I have two questions:

First I have a hard time thinking about if and how to use this hook in production. I am using webpack with css modules for the client side and this require hook on the server side when doing server side rendering of react components. In my production environment I am planning to use ExtractTextPlugin to extract all the css. Currently we are still in development.

What I notice so far is that the require hook is setting the correct classes but it does not include any generated css in the server rendered templates. So I actually get flashes of unstyled content until client side (webpack) picks up, which then inlines the styles into the html. Is this expected behaviour?
Also are there any performance hogs to be expected in production (compiling scss in runtime sounds like it). What is best practice here for setting up this hook for both development and production?

second question:

I have lots of components and lots of scss files. In these files I am importing most of the times other .scss files such as variables and mixins from a shared folder.
Webpack allows a configuration for modulesDirectories, similar to this hook's includePaths.

The problem is, that with webpack I have to prepend imports from these custom directories with a tilde. e.g.:
@import '~styles/variables'; instead of @import '../../../../styles/variables';

The tilde prefix breaks this require hook, here it would work with just @import 'styles/variables';
Any idea how to solve this?

Here is my current setup:

const cssRequireHook = require('css-modules-require-hook');
const sass = require('node-sass');
const path = require('path');
const nameScope = process.env.NODE_ENV === 'test' ? '[local]' : '[name]__[local]___[hash:base64:5]';

cssRequireHook({
    generateScopedName: nameScope,
    extensions: ['.scss', '.css'],
    preprocessCss: (data, filename) => sass.renderSync({
        data,
        file: filename,
        includePaths: [path.resolve(__dirname, '../../client')]
    }).css
});
@wuct
Copy link

wuct commented Jun 1, 2016

I have same questions and still try to figure out the best solution.

In addition to modulesDirectories, I also want to know how to handle the reslove.alias of webpack's config.

@tmaximini
Copy link
Author

From my experience so far:

  1. It is definitely okay to use this hook in production. You can check the actual compile times when you run your server with DEBUG=css-modules:*. This shows that the first render is actually pretty slow as all the css modules are compiled in run-time but all subsequent requests are being served from cache and so we decided it is feasable to run this in production.

  2. As modulesDirectories is a webpack feature I found it to be not possible to do server-side rendering of css-modules using this feature, and so our team decided to always use relative paths for requiring styles.

Hope that helps.

@wuct
Copy link

wuct commented Jun 2, 2016

@tmaximini Thanks for answering. There are useful information.

@mightyaleksey
Copy link
Member

@tmaximini @wuct sorry guys for the late call. I'll try to answer according to my experience.

I don't see any problem to use it in production, since it extends the default require function. By default Node.js caches all the require calls, so it will be slow on the start (since you need to extract tokens from all the require calls). I think, I can boost it a little better in future by caching all the calls betweens sessions.

What I notice so far is that the require hook is setting the correct classes but it does not include any generated css in the server rendered templates. So I actually get flashes of unstyled content until client side (webpack) picks up, which then inlines the styles into the html. Is this expected behaviour?

Can you describe the problem a bit more detailed?

Talking about second question. Currently, there is no support for ~ in paths, as you mentioned, but if all such calls take place in CSS it should be possible to support. I'm not familiar with sass, but with postcss it can be solve easily. Unfortunately in that case you'll have to preprocess all the files three times — with postcss, sass and postcss again.
Presumably that problem can be solved with sass also. Looks like importer option provides possibility to add some heuristic to the path resolving mechanic. Have you tried it?

Talking about webpack resolve.alias — I do see any good possibility to add it currently. Still you may checked the NODE_PATH global variable. It doesn't provide any possibility to rename modules, but it allows you to add the custom folders in which modules will be looked for.

@tmaximini
Copy link
Author

thanks @sullenor
Regarding that comment that you quoted, the unstyled content came from different generated hashs on webpack compilation and require-hook compilation, due to different folder structure (transpiled server code into a /dist subfolder for production).
I fixed this by using rootDir in the hook and context in the css-loader.
This issue can be closed from my side if you wish.

@mightyaleksey
Copy link
Member

mightyaleksey commented Jun 3, 2016

@tmaximini yeah, I got it, thank you.

I wonder if I add any adapter to support sass, will it be useful for you? And what kind of configuration would you like to see in it?

@Jezternz
Copy link

Regarding the flashes, I was able to solve this by following the directions in #53.

@figalex
Copy link

figalex commented Mar 29, 2017

@tmaximini @Jezternz I'm having the same problem with unstyled server side rendered content. I did not understand what was your solution to that problem and the small example provided on this repo uses ExtractTextPlugin on webpack config but I don't want to use this plugin on development.

Could you please show me what is your webpack configuration? Are you using webpack for both server and client side code?

@Jezternz
Copy link

Jezternz commented Mar 30, 2017

@figalex Not sure if this will help you, but this is what I use (for my universal react app - used for both development/production)

@figalex
Copy link

figalex commented Mar 30, 2017

@Jezternz Thanks! with this setup are you able to automatically reload styles when you change a css file?

@Jezternz
Copy link

@figalex Just checked and I apologise, it does not seem to be doing that. Strangely it registers the change and even sends a notification to client, but the style doesn't update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants