webpackcss-loader

I don't know how to configure the latest version of css-loader


Using the latest version of css-loader with Webpack 5.91.0, the imported CSS modules are always undefined when enabling cssModules. (This issue was resolved by downgrading css-loader to version 5.0.0.) So, does anyone know how to configure cssModules with the latest version of css-loader (7.1.1)? I think there might be a bug.

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { loader } = require('mini-css-extract-plugin');

const isProduction = process.env.NODE_ENV == 'production';

const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : 'style-loader';

const config = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
    },
    devServer: {
        open: true,
        host: 'localhost',
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html',
        }),

        // Add your plugins here
        // Learn more about plugins from https://webpack.js.org/configuration/plugins/
    ],
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/i,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env', '@babel/preset-react']
                    }
                }
            },
            {
                test: /\.css$/i,
                use: [stylesHandler,'css-loader'],
            },
            {
                test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
                type: 'asset',
            },

            // Add your rules for custom modules here
            // Learn more about loaders from https://webpack.js.org/loaders/
        ],
    },
    resolve: {
        alias: {
            '@': path.resolve(__dirname, 'src')
        },
        extensions: ['.js', '.jsx'],

    }
};

module.exports = () => {
    if (isProduction) {
        config.mode = 'production';
        
        config.plugins.push(new MiniCssExtractPlugin());
        
        
    } else {
        config.mode = 'development';
    }
    return config;
};

App.jsx

import React from "react";
import styles from "./app.module.css";
function App() {
  console.log("styles-->", styles);
  return <div className={styles?.red}>react-app</div>;
}

export default App;

Please tell me how to solve this problem.


Solution

  • There was a breaking change in v7.0.0 of css-loader. See the changelog of the package: css-loader changelog

    If you are using the default import syntax, as opposed to the namespace import syntax, you will get undefined.

    import styles from './styles.scss' // Default Import
    import * as styles from './styles.scss' // Namespace Import
    

    You can revert to using the default import syntax if you prefer by adjusting the options of the css-loader within the webpack configuration:

    module.exports = {
      module: {
        rules: [
          {
            test: /\.css$/i,
            loader: "css-loader",
            options: {
              modules: {
                namedExport: false,
                exportLocalsConvention: 'as-is',
                //
                // or, if you prefer camelcase style
                //
                // exportLocalsConvention: 'camel-case-only'
              },
            },
          },
        ],
      },
    };