Storybook v7中React组件的.scss模块样式加载问题
解决Storybook v7中SCSS模块样式不加载的问题
针对你用TypeScript+React+Parcel+Node.js技术栈,在Storybook v7里SCSS模块样式不生效、自定义webpack配置触发webpack-hot-middleware错误的问题,给你几个可行的修复步骤:
1. 清理冲突的样式插件
@storybook/preset-scss和@storybook/addon-styling在v7版本存在功能重叠,同时使用会导致解析逻辑冲突。直接移除@storybook/preset-scss,只保留官方推荐的@storybook/addon-styling。
2. 正确配置@storybook/addon-styling处理SCSS模块
在.storybook/main.ts里配置addon-styling,明确指定SCSS模块的解析规则,和你的Parcel项目保持一致:
import type { StorybookConfig } from '@storybook/react-webpack5'; const config: StorybookConfig = { stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'], addons: [ '@storybook/addon-links', '@storybook/addon-essentials', { name: '@storybook/addon-styling', options: { sass: { implementation: require('sass'), sassOptions: { module: { rules: [ { test: /\.module\.scss$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: { localIdentName: '[name]__[local]--[hash:base64:5]', // 和Parcel的类名命名规则对齐 }, }, }, 'sass-loader', ], }, { test: /\.scss$/, exclude: /\.module\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'], }, ], }, }, }, }, }, ], framework: { name: '@storybook/react-webpack5', options: {}, }, }; export default config;
3. 修复webpack-hot-middleware错误
你之前遇到的ModuleNotFoundError是因为直接替换了webpackFinal的默认配置,丢失了Storybook内置的热加载相关规则。正确的做法是合并默认配置,而不是完全重写。如果必须自定义规则,使用webpack-merge来合并:
import { merge } from 'webpack-merge'; import type { StorybookConfig } from '@storybook/react-webpack5'; const config: StorybookConfig = { // ...其他基础配置 webpackFinal: async (baseConfig) => { const customConfig = { // 只添加你需要的额外规则,不要覆盖全部module.rules module: { rules: [ // 这里放你的自定义loader规则 ], }, }; return merge(baseConfig, customConfig); }, };
4. 验证预览配置
确保.storybook/preview.tsx里只引入全局样式,不要重复引入组件的SCSS模块:
import '../src/global.scss'; // 仅全局样式引入 import type { Preview } from '@storybook/react'; const preview: Preview = { parameters: { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, }, }, }; export default preview;
5. 测试组件样式
用你提供的测试组件验证:
// TestComp.tsx import React from "react"; import * as styles from "./test.module.scss"; export const TestThing: React.FunctionComponent = () => { return <div className={styles.thing}>test</div>; }; export const TestInline: React.FunctionComponent = () => { return <div style={{ height: "50px", width: "50px", backgroundColor: "red" }}>test</div>; };
// test.module.scss .thing { background-color: red; width: 50px; height: 50px; }
启动Storybook后,TestThing组件应该和TestInline显示一致的红色方块。
额外注意事项
- 确保安装了所有必要依赖:
sass、sass-loader、css-loader、style-loader - 检查Parcel的SCSS模块自定义配置,确保和Storybook的
localIdentName一致,避免类名不匹配 - 清理node_modules和Storybook缓存(执行
npx storybook clean)后重新启动
内容的提问来源于stack exchange,提问作者Frisedel
相关产品推荐
相关产品推荐

