webpack/css-loader

The @scope rule does not generate class name in CSS Modules

Closed this issue · 6 comments

Bug report

If I try to import certain class names from *.module.css files that are declared only with @scope rule, I receive undefined instead of a proper class name.

Actual Behavior

And the problem is: the styles are not applied. css-loader correctly compile the CSS, in my HTML file everything is okay. But styles.root contains undefined.

Expected Behavior

The class name should be defined.

I found a workaround: you can simply add the usage of a desired class name outside of @scope rule (in my case .root {}) into your CSS file. But it feels like, CSS Modules should work with @scope rule without such the workaround.

How Do We Reproduce?

Here's a snippet of CSS code:

@scope (.root) {
  :scope {
    color: blue;
  }

  h1 {
    font-size: 12px;
  }
}

And this is how I use it in JavaScript

import styles from './1.module.css';

// styles.root is undefined
document.body.innerHTML = `
  <main class="${styles.root}">
    <h1>Title</h1>
  </main>
`;

console.log(styles); // empty object

Webpack configuration:

const HtmlPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'production',
  devtool: false,
  entry: './1.js',
  target: 'web',
  module: {
    rules: [{
      test: /\.css$/,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            modules: true
          },
        },
      ]
    }],
  },
  plugins: [
    new HtmlPlugin(),
  ],
};

Please paste the results of npx webpack-cli info here, and mention other relevant information

System:
    OS: macOS 14.3.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 85.67 MB / 16.00 GB
  Binaries:
    Node: 20.11.1 - ~/.nvm/versions/node/v20.11.1/bin/node
    npm: 10.2.4 - ~/.nvm/versions/node/v20.11.1/bin/npm
  Browsers:
    Chrome: 123.0.6312.87
    Safari: 17.3.1
  Packages:
    css-loader: ^6.10.0 => 6.10.0 
    html-webpack-plugin: ^5.6.0 => 5.6.0 
    style-loader: ^3.3.4 => 3.3.4 
    webpack: ^5.91.0 => 5.91.0 
    webpack-cli: ^5.1.4 => 5.1.4 
    webpack-dev-server: ^5.0.4 => 5.0.4 

There's a mistake in my code, but if I type & h1 instead of h1, styles.root will remain to be undefined

I see, we need to inject empty class in such case, if you want you can send a PR

Can't we just add the class name to the javascript object? The class name does exist, the CSS is compiled fine, the problem is only with the undefined

hm, we have a test case https://github.com/webpack-contrib/css-loader/blob/master/test/__snapshots__/modules-option.test.js.snap#L10313, but yeah, I see we don't add .kthHR5ALtmYK9QgapjA3 to export

I think we need just change false on true here https://github.com/css-modules/postcss-modules-scope/blob/master/src/index.js#L333, try it locally, if it helps feel free to send a PR

Fixed, update your transitive deps