You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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"
  }
}

报错信息

Storybook编译报错截图

解决方案

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:52:03