gajus / babel-plugin-react-css-modules

Transforms styleName to className using compile time CSS module resolution.
Other
2.05k stars 162 forks source link

Unknown error from PostCSS plugin #264

Closed ElForastero closed 4 years ago

ElForastero commented 5 years ago

I have an error using the plugin with css-loader.

Unknown error from PostCSS plugin. Your current PostCSS version is 7.0.17, but postcss-modules-scope uses 6.0.23. Perhaps this is the source of the error below.

And the stack trace:

TypeError: Cannot read property 'replace' of undefined
    at /Users/forastero/www/project/components/Project/Footer/mobile/Footer.css:1:1
    at escape (/Users/forastero/www/project/node_modules/css-selector-tokenizer/lib/stringify.js:16:14)
    at stringifyWithoutBeforeAfter (/Users/forastero/www/project/node_modules/css-selector-tokenizer/lib/stringify.js:31:16)
    at stringify (/Users/forastero/www/project/node_modules/css-selector-tokenizer/lib/stringify.js:57:12)
    at Array.map (<anonymous>)
    at stringifyWithoutBeforeAfter (/Users/forastero/www/project/node_modules/css-selector-tokenizer/lib/stringify.js:27:21)
    at stringify (/Users/forastero/www/project/node_modules/css-selector-tokenizer/lib/stringify.js:57:12)
    at Array.map (<anonymous>)
    at stringifyWithoutBeforeAfter (/Users/forastero/www/project/node_modules/css-selector-tokenizer/lib/stringify.js:27:21)
    at stringify (/Users/forastero/www/project/node_modules/css-selector-tokenizer/lib/stringify.js:57:12)
    at Array.map (<anonymous>)
    at stringifyWithoutBeforeAfter (/Users/forastero/www/project/node_modules/css-selector-tokenizer/lib/stringify.js:25:21)
    at Object.stringify (/Users/forastero/www/project/node_modules/css-selector-tokenizer/lib/stringify.js:57:12)
    at /Users/forastero/www/project/node_modules/postcss-modules-scope/lib/index.js:104:57
    at /Users/forastero/www/project/node_modules/postcss/lib/container.js:239:18
    at /Users/forastero/www/project/node_modules/postcss/lib/container.js:135:18
    at Root.each (/Users/forastero/www/project/node_modules/postcss/lib/container.js:101:16)$

I've tried to disable postcss-loader, rolling back css-loader from 3.0.0 to 2.1.1...

Nothing helps, except removing react-css-modules from babel plugins.

ElForastero commented 4 years ago

The issue was solved. We had an error in our Webpack build logic.

This is unclear from the error message, but the error was related to the difference in chunks between desktop and mobile builds.

We are using obfuscated class names, saving them into the .json file after server build (SSR).

Some mobile CSS chunks were not present in this .json file with minimized class names.

So, when the plugin tried to find names in this cache file we had this error.

Hope this can help someone.

gajus commented 4 years ago

It is not clear from the follow up what was the solution:

Did you just clear the cache?

ElForastero commented 4 years ago

I've checked the server entry point and realized that we are using desktop routes (they are split with loadable-components in our case).

So, when the server was built, it didn't generate some class names for mobile. It didn't know about those components and pages.

The file that server generates looks like this:

{
  "app/Users/forastero/www/project/app/AppMobile.css": "a_a",
  "app/Users/forastero/www/project/app/AppDesktop.css": "a_a",
  "container/Users/forastero/www/project/components/Base/Notification/Transitions/Bottom/Bottom.css": "b_c",
  "red/Users/forastero/www/project/components/Base/Notification/Transitions/Bottom/Bottom.css": "b_e",
  "green/Users/forastero/www/project/components/Base/Notification/Transitions/Bottom/Bottom.css": "b_f",
  "...": "..."
}

In our case, it didn't contain for example this line:

"app/Users/forastero/www/project/app/AppMobile.css": "a_a"

When the time comes to get a scoped name, our function returnsundefined:

/**
 * Read class names generated during server build
 */
const classNamesMap = JSON.parse(fs.readFileSync('./app/classNamesMap.json'));
const generateScopedName = (localName, resourcePath) => classNamesMap[`${localName}${resourcePath}`];

Stupid mistake. )

Maybe some warning during build stage will be a good idea. But not css-loader nor react-css-modules informed us about undefined returned from generateScopedName and getLocalIdent.