React组件库中Storybook无法编译SCSS Modules问题求助
React组件库启用SCSS Modules后Storybook编译失败问题排查
我正在开发一个React组件库,用Storybook做组件可视化展示。未启用SCSS Modules时组件加载正常,但开启SCSS Modules做样式隔离后,出现编译失败的问题。以下是我的配置文件和报错信息,求解决如何正确配置SCSS Modules的问题。
配置文件
main.ts 配置
import type { StorybookConfig } from "@storybook/react-webpack5"; const path = require('path') const config: StorybookConfig = { stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], addons: [ "@storybook/addon-webpack5-compiler-swc", "@storybook/addon-onboarding", "@storybook/addon-links", "@storybook/addon-essentials", "@chromatic-com/storybook", "@storybook/addon-interactions", "@storybook/addon-styling-webpack", "@storybook/preset-scss" ], framework: { name: "@storybook/react-webpack5", options: {}, }, webpackFinal: async (config: any) => { // Find and remove the existing css rule that conflicts with css module handling config.module.rules = config.module.rules.filter( (rule) => !rule.test || !rule.test.test('.css') ); config.module.rules.push({ test: /\.scss$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: true, importLoaders: 1, }, }, 'sass-loader', ], include: path.resolve(__dirname, '../src'), }); return config; }, }; export default config;
package.json 内容
{ "name": "ultimatix-ui", "version": "1.0.6", "description": "", "scripts": { "rollup": "rollup -c", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", "dev": "rollup -c --watch", "test": "jest" }, "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.24.5", "@babel/preset-env": "^7.24.5", "@babel/preset-react": "^7.24.1", "@babel/preset-typescript": "^7.24.1", "@chromatic-com/storybook": "^1.4.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@storybook/addon-essentials": "^8.1.2", "@storybook/addon-interactions": "^8.1.2", "@storybook/addon-links": "^8.1.2", "@storybook/addon-onboarding": "^8.1.2", "@storybook/addon-styling-webpack": "^1.0.0", "@storybook/addon-webpack5-compiler-swc": "^1.0.2", "@storybook/blocks": "^8.1.2", "@storybook/preset-scss": "^1.0.3", "@storybook/react": "^8.1.2", "@storybook/react-webpack5": "^8.1.2", "@storybook/test": "^8.1.2", "@testing-library/react": "^15.0.7", "@types/jest": "^29.5.12", "@types/react": "^18.3.2", "autoprefixer": "^10.4.19", "babel-jest": "^29.7.0", "css-loader": "^5.2.7", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "node-sass": "^9.0.0", "postcss": "^8.4.38", "react-dom": "^18.3.1", "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", "rollup-plugin-peer-deps-external": "^2.2.4", "rollup-plugin-postcss": "^4.0.2", "rollup-plugin-sass": "^1.12.22", "rollup-plugin-scss": "^4.0.0", "sass": "^1.77.2", "sass-loader": "^10.5.2", "storybook": "^8.1.2", "style-loader": "^2.0.0", "tailwind": "^4.0.0", "tslib": "^2.6.2", "typescript": "^5.4.5" }, "main": "dist/cjs/index.js", "module": "dist/esm/index.js", "files": [ "dist" ], "types": "dist/index.d.ts", "peerDependencies": { "react": "^18.3.1" } }
报错信息

解决方案
1. 移除冲突的SCSS预设
@storybook/preset-scss会自动添加SCSS处理规则,和你在webpackFinal中自定义的规则冲突。直接从addons数组中移除这个预设:
addons: [ "@storybook/addon-webpack5-compiler-swc", "@storybook/addon-onboarding", "@storybook/addon-links", "@storybook/addon-essentials", "@chromatic-com/storybook", "@storybook/addon-interactions", "@storybook/addon-styling-webpack" // 移除@storybook/preset-scss ],
2. 区分SCSS Modules和全局SCSS规则
不要给所有.scss文件启用Modules,只针对带.module.scss后缀的文件处理,避免影响全局样式。修改webpackFinal中的规则:
webpackFinal: async (config: any) => { // 过滤掉现有的SCSS/CSS规则 config.module.rules = config.module.rules.filter( (rule) => !(rule.test?.test('.css') || rule.test?.test('.scss')) ); // 处理SCSS Modules config.module.rules.push({ test: /\.module\.scss$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: { localIdentName: '[name]__[local]___[hash:base64:5]', // 自定义类名格式,可选 }, importLoaders: 1, }, }, 'sass-loader', ], include: path.resolve(__dirname, '../src'), }); // 处理全局SCSS(不带.module后缀的) config.module.rules.push({ test: /\.scss$/, exclude: /\.module\.scss$/, use: [ 'style-loader', 'css-loader', 'sass-loader', ], include: path.resolve(__dirname, '../src'), }); return config; },
3. 升级css-loader版本
你当前使用的css-loader@5.2.7版本较旧,和Webpack 5、Storybook 8兼容性可能存在问题。执行命令升级到稳定版本:
npm install css-loader@6.8.1 --save-dev
4. 确保组件中正确导入SCSS Modules
组件中必须导入带.module.scss后缀的文件,并通过导出的样式对象使用类名:
import styles from './Button.module.scss'; const Button = () => { return <button className={styles.button}>点击我</button>; };
5. 检查TypeScript类型支持(可选)
如果使用TypeScript,需要添加SCSS Modules的类型声明文件,在src目录下创建declarations.d.ts:
declare module '*.module.scss' { const classes: { [key: string]: string }; export default classes; }
内容的提问来源于stack exchange,提问作者Aadhit Shanmugam
相关产品推荐
相关产品推荐

