rails / webpacker

Use Webpack to manage app-like JavaScript modules in Rails
MIT License
5.31k stars 1.47k forks source link

`localIdentName` option moved in css-loader configuration #2197

Closed jfly closed 3 years ago

jfly commented 5 years ago

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
      }
    },
jakeNiemiec commented 5 years ago

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

gyurcigyurma commented 5 years ago

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.

davidlbean commented 5 years ago

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

jfly commented 5 years ago

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/webpacker@4.0.7
│  ├─ css-loader@^2.1.1
...
├─ css-loader@3.2.0
...

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 css-loader@2.1.1 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.

mmaloon commented 5 years ago

2130

chiptus commented 4 years ago

any workaround until webpacker gets a new version?

eZii-jester-data commented 4 years ago

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

aliraza-dev commented 4 years ago

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

Xotonori commented 4 years ago

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.

jonibekk commented 4 years ago

I think you don't need localIdentName,

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

this worked for me

hazyikmis commented 4 years ago

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...

Bhagi001 commented 4 years ago

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

Ashfiii commented 4 years ago

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.

hazyikmis commented 4 years ago

No need to thanks bro 👍

rockus123 commented 4 years ago

It looks like all these things keep changing.

ohadkoren commented 3 years ago

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.

ghasemikasra39 commented 3 years ago

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 :))

austinkeller commented 3 years ago

You can get CSS modules working without having to eject by following the guide here: https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/

Essentially, just rename App.css to App.module.css (and update the import to import classes from "./App.module.css"')

mjones12209 commented 3 years ago

You could also go to where the getStyleLoader function is called and edit it like so:

image

symplrr commented 3 years ago

I think we don't need to tweak around with this anymore. Cause after react version 4.

We already have this in the getCSSModuleLocalIdent.js file.

image

The getCSSModuleLocalIdent.js file image

It already has it in place. Please correct me, if my interpretation is wrong.

Thanks!

varejy commented 3 years ago

У меня возникла такая же проблема после загрузки css-loader, но я ее решил.

Если вы проверите файл readme css-loader, то я заметил, что localIdentName переместился в ключ модулей (возможно, это не недавнее изменение, просто мои артефакты были старыми). Моя текущая рабочая конфигурация:

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

Старая неправильная конфигурация была:

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

Может, ты тоже сможешь это проверить.

Thank you so much ! It helped ; }

vladworldss commented 3 years ago

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.

God bless you man. It's fixed my compile problem "css-loader": "4.3.0", node==v14.15.5