preview.js中import Less编译后的CSS才能生效,因preview.js不解析Less语法,需先用lessc等工具将.less编译为.css(如../dist/styles.css),再在preview.js中import该产物,路径须从.storybook目录出发正确计算。

preview.js 里 import Less 编译后的 CSS 才能生效
Storybook 的 preview.js 不解析 Less 语法,直接 import '../src/styles/button.less' 必然报错 You may need an appropriate loader。它只接受纯 CSS 字节流——所以你得先编译好 Less,再 import 这个产物。
常见做法是:用 lessc 或构建脚本把 src/styles/index.less 编译成 dist/styles.css,然后在 preview.js 中写:
import '../dist/styles.css';
这样注入的样式会以 <style> 标签形式出现在预览 iframe 的 <head> 中,真正全局生效。
- 路径必须从
.storybook/目录出发计算,../dist/styles.css是对的,./dist/styles.css或dist/styles.css都会失败 - 确保编译时启用了
--strict-math=on和--include-path(尤其当用了@import "../core/variables") - 别在编译产物里留
@import url(),跨域或路径错误会导致样式静默丢失,且控制台可能不报错
要用 Less 变量和 mixin,必须配 webpackFinal + less-loader
如果你的组件内部写了 .button { .flex-center(); color: @primary-color; },光靠编译后 CSS 是不够的——变量和 mixin 要在组件样式文件被加载时就可用,这需要构建时介入。
立即学习“前端免费学习笔记(深入)”;
在 .storybook/main.js 的 webpackFinal 中加规则:
webpackFinal: async (config) => {
config.module.rules.push({
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'],
include: path.resolve(__dirname, '../src'),
options: {
lessOptions: {
paths: [path.resolve(__dirname, '../src/styles')],
javascriptEnabled: true,
}
}
});
return config;
}
这个配置让 Button.module.less 里的 @import 'variables'; 和 .button-base() 能正常解析,但注意:
- 它不影响
preview.js的 import 行为,两者职责分离:一个管组件内样式构建,一个管预览环境全局基底 -
lessOptions.paths必须显式声明,Less 不走 Webpack 的resolve.alias,漏掉就会报Cannot resolve variable @text-color - 不要在
preview.js里同时import未编译的 .less 文件,否则构建直接中断
命名空间和顶层 class 是防止样式泄漏的关键
Less 没有天然作用域,.btn() { color: red; } 在全局调用会污染所有 .btn 类名。Storybook 预览 iframe 是独立上下文,但你的组件若没约束范围,样式仍可能意外覆盖 Storybook 自身 UI 或其他 story。
正确姿势是强制所有组件样式包裹在唯一命名空间下,比如:
.ui-kit .button {
.button-base();
.button-size(@size);
.button-theme(@theme);
}
对应 HTML 容器必须带 class="ui-kit",否则样式不触发。这不是可选建议,而是模块化落地的硬性边界:
- 禁止在 mixin 内写裸选择器(如
.clearfix),所有样式必须通过.ui-kit &或嵌套结构生成 - 所有
@import必须指向语义化路径(如@import "core/variables"),不能用相对跳转(@import "../../mixins/flex") - 如果用了
@storybook/addon-html预览纯 HTML 片段,也得手动加上<div class="ui-kit">...</div>
怎么确认 Less 相关样式真正在预览中起效
别信控制台有没有报错,要查两处 DOM:
第一,打开任意 story,进开发者工具 → Elements → 找到预览 iframe → 展开 <head>,确认你编译后的 styles.css 是否以 <style> 标签存在;
第二,在同一 iframe 的 <body> 里找组件容器,右键检查元素,看 computed styles 是否包含你定义的 @primary-color 值、.flex-center 生成的 flex 规则等。
- 如果第一处没
<style>,说明preview.jsimport 失败,回溯路径和文件内容 - 如果第一处有但第二处没生效,大概率是命名空间缺失(容器没
ui-kitclass)或 CSS 优先级被组件内联 style 覆盖 - 如果变量值显示为
undefined或 fallback 颜色,说明webpackFinal中less-loader的paths或javascriptEnabled没配对
最易被忽略的是:Less 编译产物和组件内动态 import 的 .less 文件,它们依赖的变量源必须一致——不能一个用 variables.less,另一个用 theme-dark.less 却没在编译链路里显式引入。


















