Css-loader: Setting "namedExport: true" actually breaks named exports

Created on 6 Jun 2021  路  5Comments  路  Source: webpack-contrib/css-loader

  • Operating System: Windows 10
  • Node Version: v12.18.3
  • NPM Version: 6.14.11
  • webpack Version: 4.44.2
  • css-loader Version: 4.3.0

Expected Behavior

Having modules: { namedExport: ... } inside the webpack.config.js unset.
Given import styles from "./styles.scss" the value of styles.cardContainer is the content of cardContainer class from the scss file.
Given import { cardContainer } from "./styles.scss" the value of cardContainer is undefined, or an exception is thrown.

Having modules: { namedExport: ... } inside the webpack.config.js set to true.
Given import styles from "./styles.scss" the value of styles.cardContainer is the content of cardContainer class from the scss file.
Given import { cardContainer } from "./styles.scss" the value of cardContainer is the content of cardContainer class from the scss file.

Actual Behavior

Having modules: { namedExport: ... } inside the webpack.config.js unset.
Given import styles from "./styles.scss" the value of styles.cardContainer is the content of cardContainer class from the scss file.
Given import { cardContainer } from "./styles.scss" the value of cardContainer is the content of cardContainer class from the scss file. Typescript error Module '"*.scss"' has no exported member 'cardContainer' is being thrown. Code still works with the use of //@ts-ignore.

Having modules: { namedExport: ... } inside the webpack.config.js set to true.
Given import styles from "./styles.scss" the value of styles.cardContainer is undefined. The value of styles is an empty object.
Given import { cardContainer } from "./styles.scss" the value of cardContainer is undefined. Typescript error Module '"*.scss"' has no exported member 'cardContainer' is being thrown.

Code

// webpack.config.js
// using the extension .module.scss or .module.sass
            {
              test: sassModuleRegex,
              use: getStyleLoaders(
                {
                  esModule: true,
                  importLoaders: 3,
                  sourceMap: isEnvProduction
                    ? shouldUseSourceMap
                    : isEnvDevelopment,
                  modules: {
                    getLocalIdent: getCSSModuleLocalIdent,
                    namedExport: true
                  }, 
                },
                'sass-loader'
              ),
// index.tsx
import { cardContainer } from  "./styles.scss";

console.log(cardContainer);

How Do We Reproduce?

  1. clone this repo https://github.com/SoundAsleep192/sass-vs-styledcomponents
  2. check out these files :
    config/webpack.config.js
    src/CardContainerSass/index.tsx
    src/CardContainerSass/CardSass/index.tsx
  3. run yarn && yarn start

Most helpful comment

When you have a problem with CRA please prefer to use CRA repo for issues.

Solutions:

  • Firstly you need to update: style-loader, mini-css-extract-plugin and css-loader to the latest versions, v1 of style-loader and v4 for css-loader have bugs with named exports, you can read it in CHANGELOG
  • when you need add:
 isEnvDevelopment && {
       loader: require.resolve('style-loader'),
        options: {
         modules: {
           namedExport: true
         }
        }
      },

for style-loader (same for mini-css-extract-plugin, in near future we will release the new version and you will not need to do this extra setup)

  • Then you need to rewrite all default import on named in src/CardContainerSass.tsx and src/CardContainerSass/CardSass/index.tsx
  • Then you need fix ts errors, unfortunately I can't found solution here, typescript-plugin-css-modules just not working, please ask about it in typescript-plugin-css-modules

Also you don't need CaseSensitivePathsPlugin with "forceConsistentCasingInFileNames": true,, it just doesn't make sense, current configuration is not good, you need change it or wait CRA update

All 5 comments

When you have a problem with CRA please prefer to use CRA repo for issues.

Solutions:

  • Firstly you need to update: style-loader, mini-css-extract-plugin and css-loader to the latest versions, v1 of style-loader and v4 for css-loader have bugs with named exports, you can read it in CHANGELOG
  • when you need add:
 isEnvDevelopment && {
       loader: require.resolve('style-loader'),
        options: {
         modules: {
           namedExport: true
         }
        }
      },

for style-loader (same for mini-css-extract-plugin, in near future we will release the new version and you will not need to do this extra setup)

  • Then you need to rewrite all default import on named in src/CardContainerSass.tsx and src/CardContainerSass/CardSass/index.tsx
  • Then you need fix ts errors, unfortunately I can't found solution here, typescript-plugin-css-modules just not working, please ask about it in typescript-plugin-css-modules

Also you don't need CaseSensitivePathsPlugin with "forceConsistentCasingInFileNames": true,, it just doesn't make sense, current configuration is not good, you need change it or wait CRA update

But you can use as workaround:

declare module '*.scss' {
  const classes: { [key: string]: string };
  export classes;
}

Feel free to feedback, unfortunately I can't fix ts problem here

Thank you for your response! :) I didn't know that those versions had bugs
However, after upgrading dependencies, I'm just getting more errors (XD), which I assume is due to a huge load of outdated webpack plugins mangled together inside the webpack.config.js file produced after ejecting CRA.
I'll just go ahead and drop this project and start anew setting babel, webpack etc. by hand

You can update deps steps by steps, should be no problems, firstly update loades, then plugins, then other tools

Was this page helpful?
0 / 5 - 0 ratings

Related issues

osenvosem picture osenvosem  路  4Comments

tapz picture tapz  路  3Comments

mareksuscak picture mareksuscak  路  5Comments

Jessidhia picture Jessidhia  路  3Comments

Naspo88 picture Naspo88  路  3Comments