✅生效:只要路径正确且文件为纯CSS或已编译的SCSS/CSS,preview.js中import全局CSS即可被Storybook预览iframe加载;❌不生效常见原因包括路径错误、语法错误、跨域@import及CSS Modules。
直接在 preview.js(或 preview.ts)里用 import 引入全局 CSS 文件,是最简单、最可靠的方式——它不依赖 Webpack 配置改动,也不需要额外 loader,适用于绝大多数 Storybook 项目(v6.5+ 到 v9.x)。
但要注意:这种方式只注入 CSS 规则,不支持 Sass 变量、mixin 或嵌套语法。如果项目依赖 _variables.scss 这类文件,光靠 import 是无效的。
preview.js 中 import 全局 CSS 是否生效?.storybook 目录出发(应使用 ../src/style/index.css).scss 写进了 import)@import url(...) 且目标资源跨域或路径不可达xxx.module.css),这类文件默认不会全局注入示例正确写法:
import '../src/style/reset.css';import '../src/style/theme.css';
preview.js 里 import Sass 文件?preview.js 是 JS 运行时上下文,不是样式构建上下文import '../src/style/variables.scss' 会报错:You may need an appropriate loader to handle this file type
sass-loader 在 Webpack 构建阶段处理,JS 文件无法“执行” Sass 逻辑所以:
立即学习“前端免费学习笔记(深入)”;
webpackFinal 配置里的 additionalData
import 到 preview.js 最省事webpackFinal 配置中如何安全注入 Sass 全局变量?这是唯一能真正让所有组件故事自动获得 $primary-color 等变量的方式。关键点:
test 正则(如 /.s[ac]ss$/)additionalData 字符串里用反引号包裹 @import,且路径需用 path.resolve 绝对化scss rule,避免冲突)推荐写法(.storybook/main.js):
const path = require('path');module.exports = { // ...其他配置 webpackFinal: async (config) => { config.module.rules.forEach(rule => { if (rule.test && rule.test.toString().includes('scss')) { rule.use.forEach(loader => { if (loader.loader?.includes('sass-loader')) { loader.options = { ...loader.options, additionalData: `@import "${path.resolve(__dirname, '../src/style/variables.scss')}";`, }; } }); } }); return config; },};
容易踩的坑:
additionalData 错配到 css-loader 上(无效)@/ 别名但没配 alias(应改用 path.resolve)sass-loader 实例导致变量被覆盖或丢失真正麻烦的从来不是“加一行 import”,而是搞清你加的到底是「运行时样式」还是「构建时上下文」。前者看 preview.js,后者必须动 webpackFinal —— 混用就白忙活。