Webpacker: `localIdentName` option moved in css-loader configuration

Created on 29 Jul 2019  ·  17Comments  ·  Source: rails/webpacker

In css-loader 3.0.0, there was a breaking change with the localIdentName configuration option:

BREAKING CHANGES

  • modules option now can be {Object} and allow to setup CSS Modules options:

    • localIdentRegExp option was removed in favor modules.localIdentRegExp option

When we upgrade to css-loader >= 3.0, we see the following crashes when compiling:

ERROR in ./app/javascript/markdown-editor/style.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/css-loader/dist/cjs.js):
ValidationError: Invalid options object. CSS Loader has been initialised using an options object that does not match the API schema.
 - options has an unknown property 'localIdentName'. These properties are valid:
   object { url?, import?, modules?, sourceMap?, importLoaders?, localsConvention?, onlyLocals? }
    at validate (/home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/css-loader/node_modules/schema-utils/dist/validate.js:49:11)
    at Object.loader (/home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/css-loader/dist/index.js:39:28)
    at runLoaders (/home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/webpack/lib/NormalModule.js:302:20)
    at /home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/loader-runner/lib/LoaderRunner.js:367:11
    at /home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/loader-runner/lib/LoaderRunner.js:233:18
    at runSyncOrAsync (/home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/loader-runner/lib/LoaderRunner.js:143:3)
    at iterateNormalLoaders (/home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/loader-runner/lib/LoaderRunner.js:232:2)
    at iterateNormalLoaders (/home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/loader-runner/lib/LoaderRunner.js:221:10)
    at /home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/loader-runner/lib/LoaderRunner.js:236:3
    at context.callback (/home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
    at postcss.process.then (/home/jeremy/gitting/worldcubeassociation.org/WcaOnRails/node_modules/postcss-loader/src/index.js:197:9)

I think the relevant webpacker source code is here https://github.com/rails/webpacker/blob/41d79c96187154b5485289e8c3c42428dd819bfc/package/utils/get_style_rule.js#L17-L26. The fix may be to do something like this instead?

const getStyleRule = (test, modules = false, preprocessors = []) => {
  if (modules) {
    modules = {
      localIdentName: '[name]__[local]___[hash:base64:5]',
    };
  }
  const use = [
    {
      loader: 'css-loader',
      options: {
        sourceMap: true,
        importLoaders: 2,
        modules
      }
    },
dependencies support

Most helpful comment

I faced same issue after upading css-loader but I solved it.

If you check css-loader readme, then I noticed that "localIdentName" moved into modules key (it is possible that isn't a recent change, just my artifacts were old).
My current working config is:

{
    loader: "css-loader",
    options: {
        modules: {
            localIdentName: "[name]__[local]___[hash:base64:5]",
        },                                                      
        sourceMap: isDevelopment
    }
}

Old wrong config was:

{
    loader: "css-loader",
    options: {
        modules: true,
        localIdentName: "[name]__[local]___[hash:base64:5]",
        sourceMap: isDevelopment
    }
}

Maybe you can check it also.

All 17 comments

Webpacker only supports css-loader versions greater than 2.1.1, and less than 3.0.0.

https://github.com/rails/webpacker/blob/cc98e59652f22c723fac0308199cff5a42ad49ce/package.json#L30

I faced same issue after upading css-loader but I solved it.

If you check css-loader readme, then I noticed that "localIdentName" moved into modules key (it is possible that isn't a recent change, just my artifacts were old).
My current working config is:

{
    loader: "css-loader",
    options: {
        modules: {
            localIdentName: "[name]__[local]___[hash:base64:5]",
        },                                                      
        sourceMap: isDevelopment
    }
}

Old wrong config was:

{
    loader: "css-loader",
    options: {
        modules: true,
        localIdentName: "[name]__[local]___[hash:base64:5]",
        sourceMap: isDevelopment
    }
}

Maybe you can check it also.

For anyone not a webpack guru (and I'm not!), I found the code @gyurcigyurma 's code suggestion in my Rails app under /node_modules/@rails/webpacker/package/utils/get_style_rule.js.

Thanks @gyurcigyurma !

image

Webpacker only supports css-loader versions greater than 2.1.1, and less than 3.0.0.

Ah, you're totally right! We periodically upgrade all our dependencies, and when we tried to upgrade css-loader, we put "css-loader": "^3.2.0" in our package.json. Unfortunately, when we did that, it looks like yarn happily installed two versions of css-loader for us:

$ grep '"version"' node_modules/**/css-loader/package.json
node_modules/css-loader/package.json:  "version": "3.2.0",
node_modules/@rails/webpacker/node_modules/css-loader/package.json:  "version": "2.1.1",
$ bin/yarn list
...
├─ @rails/[email protected]
│  ├─ css-loader@^2.1.1
...
├─ [email protected]
...

It looks like when we actually run webpack, css-loader actually gets loaded by loader-runner, which causes us to load css-loader version 3.2.0, despite the fact that version 2.1.1 is installed! My understanding of https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders is that if the require('css-loader') had instead been done by @rails/webpacker code, it would have instead installed css-loader version 2.1.1.

I'm not sure what the right fix for this is... maybe webpacker should actually specify [email protected] as a peerDependency? If you want to play around with this, I put a simple repro over on https://github.com/jfly/css-loader-issues.

2130

any workaround until webpacker gets a new version?

Webpacker only supports css-loader versions greater than 2.1.1, and less than 3.0.0.

https://github.com/rails/webpacker/blob/cc98e59652f22c723fac0308199cff5a42ad49ce/package.json#L30

In css-loader: 3.2, inside getStyleLoaders method, just replace options: cssOptions with options: { modules: { localIdentName: "[name]__[local]___[hash:base64:5]" } }

I faced same issue, when I took a course on react.

So it was before:
loader: require.resolve('css-loader'),
options: cssOptions,

Do it and it works:
loader: require.resolve('css-loader'),
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}

Hope I helped somebody.

I think you don't need localIdentName,

{ test: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }), },

this worked for me

After ejecting, you need to make changes just on config/webpack.config.js file.
In this file, please find: module:rules:use: getStyleLoaders({...
And add modules: true just after importLoaders: 1
No need to put localIdentName... If you put, you will get an error.

The changed section should be look like below:

use: getStyleLoaders({
   importLoaders: 1,
   modules: true,
   sourceMap: isEnvProduction && shouldUseSourceMap
})

And now, good to go...

For anyone not a webpack guru (and I'm not!), I found the code @gyurcigyurma 's code suggestion in my Rails app under /node_modules/@rails/webpacker/package/utils/get_style_rule.js.

Thanks @gyurcigyurma !

image

Solved the problem, thanks man

I faced same issue, when I took a course on react.

So it was before:
loader: require.resolve('css-loader'),
options: cssOptions,

Do it and it works:
loader: require.resolve('css-loader'),
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}

Hope I helped somebody.

Thank you brother!
This worked for me.

No need to thanks bro 👍

It looks like all these things keep changing.

Do it and it works:
loader: require.resolve('css-loader'),
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}

Works for me as of this date, thanks!

It looks like all these things keep changing.

That's a real problem but I guess the community is working on it.
Very common problem.

localIdentName: '[name]__[local]__[hash:base64:5]'

I am using "webpack": "4.42.0" and your solution works perfectly.
Btw I am watching the same course others mentioned above :)
I think we are all watching the same course :))

Was this page helpful?
0 / 5 - 0 ratings