Skip to content

Issues migrating from babel-plugin-css-modules-transform with dart-sass #36

Closed
@kapowaz

Description

@kapowaz

I’m migrating an older project which uses babel-plugin-css-modules-transform, and after some research I discovered you now recommend your babel-plugin-react-css-modules babel plugin as an alternative approach, as the previous packages are all abandoned/outdated.

My project setup involves React + TypeScript with SCSS. The package is published in two parts: an NPM package containing babelified JS files representing React components as CommonJS, plus a manifest file, and a set of static assets (a single minified CSS file, fonts etc.) which are published to a CDN.

The publish pipeline also runs in two parts: first it uses webpack to compile the Sass into the stylesheet published on the CDN, and then it uses babel to compile the respective JS files. As part of this process I have always used css-modules-transform to add the var styles = { ... } object to each component. So, assuming I start out with:

// styles.scss
.someClassName {
  color: red;
}
/* MyComponent.tsx */
import styles from './styles.scss';

export const MyComponent = () => <div className={styles.someClassName}>hello world</div>;

I would expect to get something like this output:

/* application.css */
.kpwz-fc6e99e5512e50ed{color:red}
/* MyComponent.js */
var styles = {
  "someClassName": "kpwz-fc6e99e5512e50ed"
};

const MyComponent = () => {
  return /*#__PURE__*/(0, _jsxRuntime.jsx)('div', {
    className: styles.someClassName,
  });
};

exports.MyComponent = MyComponent;

All of the above has been working fine with my existing setup, and I’m using it successfully on a couple of sites (e.g. here). But a bunch of the internals were a little outdated, so I’ve started the work to gradually upgrade from e.g. webpack 4 to 5, babel 6 to 7, node 14 to 16 (so far).

However, the upgrade from node-sass to dart-sass has blocked all of this: for whatever reason the ident name generated by generateScopedName is different between the stylesheets emitted by webpack and the styles = { ... } block appended to the component by babel-plugin-css-modules-transform. I’ve exhausted all the paths I feel I can explore (for my level of knowledge of babel, at least) to try and understand why this is happening, but as best as I can tell, something about the different way that the ident name is being determined from babel-plugin-css-modules-transform compared to webpack (with css-loader, postcss-loader and sass-loader) is resulting in these different classnames.

Circling back to the start, I discovered your package and it sounds like it should solve the problem I have, but I’m not able to get it to output the var styles = { ... } block in the published component, despite following what the readme suggests. This is the config I have in my .babelrc:

"plugins": [
  "@babel/plugin-proposal-class-properties",
  "add-react-displayname",
  [
    "@dr.pogodin/react-css-modules",
    {
      "generateScopedName": "kpwz-[contenthash:16]",
      "replaceImport": true
    }
  ]
]

For completeness, here is the equivalent section of my webpack.config.js:

{
  test: /\.scss$/,
  use: [
    {
      loader: MiniCssExtractPlugin.loader,
    },
    {
      loader: 'css-loader',
      options: {
        modules: { localIdentName: 'kpwz-[contenthash:16]' },
        sourceMap: false,
      },
    },
    {
      loader: 'postcss-loader',
      options: {
        postcssOptions: {
          plugins: [cssnano()],
        },
      },
    },
    {
      loader: 'sass-loader',
      options: {
        implementation: require('sass'),
      },
    },
  ],
},

What am I missing from my config to get the desired output?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions