michalkvasnicak / babel-plugin-css-modules-transform

Extract css class names from required css module files, so we can render it on server.
MIT License
326 stars 54 forks source link

Cache issues with CSS #33

Closed pronebird closed 7 years ago

pronebird commented 7 years ago

For some unknown reason extracted CSS is only saved to disk once. All subsequent changes to CSS are no-op.

NODE_ENV is set to development.

Config:

{
  "presets": ["es2015", "stage-0", "react"],
  "plugins": ["transform-decorators-legacy", "transform-runtime", [
    "css-modules-transform", {
      "extractCss": "./build/assets/style.compiled.css",
      "devMode": true
    }
  ]]
}

This is the log from browser-sync:

[BS] File changed: build/components/Login.css
[BS] File changed: build/assets/style.compiled.css
app/components/Login.js -> build/components/Login.js
[BS] File changed: build/components/Login.js.map
[BS] File changed: build/components/Login.js
[BS] File changed: build/components/Login.css
app/components/Login.js -> build/components/Login.js
[BS] File changed: build/components/Login.js.map
[BS] File changed: build/components/Login.js
[BS] File changed: build/components/Login.css
[BS] File changed: build/components/Login.css
app/components/Login.js -> build/components/Login.js
[BS] File changed: build/components/Login.js.map
[BS] File changed: build/components/Login.js
app/components/Login.js -> build/components/Login.js
[BS] File changed: build/components/Login.js.map
[BS] File changed: build/components/Login.js
app/components/Login.js -> build/components/Login.js
[BS] File changed: build/components/Login.js.map
[BS] File changed: build/components/Login.js
app/components/Login.js -> build/components/Login.js
[BS] File changed: build/components/Login.css
[BS] File changed: build/components/Login.js.map
[BS] File changed: build/components/Login.js
screenshot 2017-02-08 12 43 54

I wrote a somewhat test to verify that there is no issue with CSS compiler. Looking at console output everything is alright.

it('should recompile generated file', () => {
    const called = [];
    const dir = `${__dirname}/output`;
    const input = `${dir}/input.css`;
    const output = `${__dirname}/output/output.css`;

    mkdirSync(dir);

    const sources = ['.class { color: red; }', '.class { color: blue; }', '.class { color: green; }'];

    for (const src of sources) {
        writeFileSync(input, src, { encoding: 'utf8' });

        const source = transform('fixtures/generated.js', {
            extractCss: output,
            processCss(css, filename) {
                called.push(relative(__dirname, filename));
                console.log(`PROCESSED ${filename}`);
                return css;
            }
        }).code;

        const generatedCSS = readFileSync(output, 'utf8');

        console.log(`!!! COMPILED:\n\n${source}\n\n!!!\n\n`);
        console.log(`!!! READ FILE: ${generatedCSS}`);
    }
});

I first run babel to precompile everything with the following options:

babel app/ --copy-files --out-dir build --source-maps true

Then I run two scripts in parallel:

Script that spins off Browser sync to reload browser on file changes:

babel-node scripts/serve.js

Babel with --watch option to recompile files on fly:

babel app/ --copy-files --out-dir build --source-maps true --watch --skip-initial-build

michalkvasnicak commented 7 years ago

@pronebird which version of this plugin are you using? If it is newest, could you try downgrade to 1.1.0?

pronebird commented 7 years ago

It's 1.2.0

npm list babel-plugin-css-modules-transform
electron-react-redux-boilerplate@0.0.0 /Users/pronebird/test
└── babel-plugin-css-modules-transform@1.2.0 

Same issue with 1.1.0. First change is OK, subsequent calls do not generate combined CSS.

pronebird commented 7 years ago

It's cache issue in requireCssFile.

You have to invalidate cache for CSS file as following:

delete require.cache[filePathOrModuleName];
michalkvasnicak commented 7 years ago

I think it is caused by this line https://github.com/michalkvasnicak/babel-plugin-css-modules-transform/blob/master/src/index.js#L95

michalkvasnicak commented 7 years ago

It's not cache issue if you enable devMode. https://github.com/css-modules/css-modules-require-hook#devmode-boolean

michalkvasnicak commented 7 years ago

Could you try to brute force change source for this plugin in the node_modules so you will workaround the line I sent you? It is faster way how to check if everything works :)

pronebird commented 7 years ago

Yeah yeah that's what I am doing right now. I've enabled devMode, gonna erase node_modules and reinstall from scratch then try couple of things you suggested. I had this commented out too... https://github.com/michalkvasnicak/babel-plugin-css-modules-transform/blob/master/src/index.js#L95

michalkvasnicak commented 7 years ago

I think that should solve the problem because we are not writing css again if a css file is transpiled.

pronebird commented 7 years ago

You're right! With devMode on and line #95 commented everything works as expected when using babel --watch

michalkvasnicak commented 7 years ago

Ok so we should change the line so it only checks cache if devMode is enabled, otherwise it will ignore changes in css files.

michalkvasnicak commented 7 years ago

I am sorry I mean opposite, to check it only if devMode is disabled.

pronebird commented 7 years ago

Is it safe to assume that if this thing is called more than once then the same class-set is produced? I mean are CSS class names deterministic or randomized on each compilation?

michalkvasnicak commented 7 years ago

I think they are generated based on css rules. So unless you don't have hashes in css names I think class names changes with rules in their definitions. But I am not sure (not an expert to css modules).

michalkvasnicak commented 7 years ago

I meant unless you have set css class name generator to ignore hashes you should have unique css classes.

michalkvasnicak commented 7 years ago

@pronebird could you try version next please? #38

pronebird commented 7 years ago

@michalkvasnicak good progress! I'll take a look at it on monday.

michalkvasnicak commented 7 years ago

Released in 1.2.6. Is not tested properly so maybe bugs will occur.