Webpack5中css-loader导致样式类名需通过.default访问的问题
问题
在使用Webpack的css-loader时遇到问题,配置了标准Webpack文件并搭配ts-loader与css-loader,构建成功后以下代码无法正常运行:
import * as css from "./AppLogoStyles.css"; ... <AppMainLogo className={css.logo} />
原因是构建后的文件中,样式类名被隐藏在css.default.logo中而非css.logo。
我的tsconfig配置如下:
{ "compilerOptions": { "module": "commonjs", "target": "es5", "sourceMap": true, "declaration": true, "jsx": "react", "skipLibCheck": true, "strictNullChecks": true } }
Webpack配置如下:
const path = require('path'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { mode: "development", entry: './src/index.ts', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist'), }, plugins: [new MiniCssExtractPlugin()], module:{ rules: [ { test:/\.css$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader", options: { modules: "global", }, }, ] }, { test:/\.ts$/, use:['ts-loader'] } ] }, };
此前在Webpack4中该配置可正常运行,升级到Webpack5后出现此问题,请问原因是什么?
原因及解决方案
这个问题是Webpack5对ES模块与CommonJS模块的互处理逻辑调整导致的:
核心原因:
Webpack5中css-loader默认启用了esModule: true配置,而Webpack4里css-loader的esModule默认值是false。当esModule设为true时,css-loader会将样式导出为ES模块格式,而你的tsconfig指定了module: commonjs,用CommonJS规范导入ES模块时,ES模块的导出会被包裹在default属性下,因此必须通过css.default.logo才能访问到类名。解决方案:
有两种可行的解决方式:- 修改css-loader配置:在css-loader的options里显式设置
esModule: false,恢复Webpack4的行为,这样导入的css对象会直接包含类名,无需通过default访问:{ loader: "css-loader", options: { modules: "global", esModule: false // 添加该配置项 }, } - 修改导入方式:改用默认导入适配ES模块的导出逻辑:
import css from "./AppLogoStyles.css"; // 之后直接使用css.logo即可
- 修改css-loader配置:在css-loader的options里显式设置
内容的提问来源于stack exchange,提问作者raz0r999
相关产品推荐
相关产品推荐

