Storybook 官方 ESLint 插件安装指南:eslint-plugin-storybook 的安装、版本匹配与配置实战
本篇指南讲解如何在 Storybook 项目中安装并启用官方 ESLint 插件 eslint-plugin-storybook:从 npm/pnpm/yarn 三种包管理器的安装命令出发,覆盖 ESLint 前置条件、ESLint 版本与插件版本匹配、.eslintrc 与 flat config 两种配置体系,以及内置推荐规则集的行为边界。读完你将能独立完成一个既有 Storybook 环境(含 React/Vue/Svelte 等任意框架)的 lint 接入,并理解该插件在源码层面如何自动识别 *.stories.* 文件、检查 .storybook/main.* 配置,从而持续保障 story 代码与 CSF(Component Story Format)规范一致。
一、eslint-plugin-storybook 是什么
eslint-plugin-storybook 是 Storybook 官方维护的 ESLint 插件,定位是"编写 story 的最佳实践规则集"。在 Storybook 仓库中,它位于 code/lib/eslint-plugin,package.json 中描述为 "Storybook ESLint Plugin: Best practice rules for writing stories",当前仓库内版本为 10.6.0-beta.1,其 peerDependencies 声明 eslint >= 8(见 code/lib/eslint-plugin/package.json)。
它可以帮你捕捉两类典型问题:
- story 代码自身的规范问题:例如缺失默认导出、重复的 story name、未使用 PascalCase 命名、误用了已废弃的
storiesOfAPI 等; - Storybook 配置文件错误:例如在 [.storybook/main.js|ts] 中把 addon 名称拼写错误或引用了未安装的 addon。
该插件内部已打包其所需的 CSF 辅助工具,因此不需要为了加载 ESLint 插件而单独安装 storybook 包(在 monorepo 共享 ESLint preset 中尤其方便),这一细节在 code/lib/eslint-plugin/README.md 中有明确说明。
二、第一步:先安装 ESLint
插件是 ESLint 的扩展,因此需要先保证项目里存在 ESLint。官方安装文档(docs/configure/integration/eslint-plugin.mdx)指出"You'll first need to install ESLint"。
eslint 本体与插件一样应作为开发依赖安装(对应安装片段见 docs/_snippets/eslint-install.md):
npm install --save-dev eslint
使用 pnpm 时:
pnpm add --save-dev eslint
使用 yarn 时:
yarn add --dev eslint
提示:官方文档站点中的安装片段用
renderer="common" packageManager="npm|pnpm|yarn"标注,表示同一命令在不同包管理器下的等价写法,实际项目中只执行与你锁定的包管理器对应的那一条即可。
三、第二步:安装 eslint-plugin-storybook
这就是本篇关联文档(docs/_snippets/eslint-plugin-storybook-install.md)的核心内容——三种包管理器下将该插件安装为开发依赖的命令。插件应始终使用 --save-dev(或 -D)写入 devDependencies。
npm:
npm install --save-dev eslint-plugin-storybook
pnpm:
pnpm add --save-dev eslint-plugin-storybook
yarn:
yarn add --dev eslint-plugin-storybook
3.1 ESLint 与插件版本的匹配关系
ESLint 的 major 版本决定了插件需要安装哪个大版本。官方文档提供了明确的对照表(见 docs/configure/integration/eslint-plugin.mdx 的 ESLint compatibility 一节):
| ESLint 版本 | Storybook 插件版本 |
|---|---|
^9.0.0 |
^9.0.0 或 ^0.10.0 |
^8.57.0 |
^9.0.0 或 ^0.10.0 |
^7.0.0 |
~0.9.0 |
需要说明两点以帮助你结合当前仓库判断:
- 上面的表格是官方集成文档中的版本指引;而当前仓库
code/lib/eslint-plugin的package.json已推进到10.6.0-beta.1(10.x 时代),其peerDependencies直接声明eslint >= 8。在跟随文档选择安装版本时,优先以你要安装的插件 dist-tag 发布说明与peerDependencies为准。 - 之所以存在严格的版本映射,是因为 ESLint 9 起 flat config 成为默认配置体系,规则 API 与配置结构都有变化,旧版插件无法直接在新版 ESLint 上加载。
四、第三步:配置插件使其生效
安装完成后还需在 ESLint 配置中启用插件。根据你使用的 ESLint 配置风格分两种情况。
4.1 传统 .eslintrc 配置(ESLint < v9)
在 .eslintrc 的 extends 中加入 plugin:storybook/recommended。官方指出可以省略 eslint-plugin- 前缀:
{
// extend plugin:storybook/<configuration>,例如:
"extends": ["plugin:storybook/recommended"]
}
自动文件范围:启用该配置后无需手动指定文件范围,插件只作用于匹配 *.stories.*(官方推荐)或 *.story.* 模式的文件。这一自动作用域在源码中可以看到其实现:推荐配置通过 overrides 的 files 字段声明的模式为 **/*.stories.@(ts|tsx|js|jsx|mjs|cjs) 与 **/*.story.@(ts|tsx|js|jsx|mjs|cjs),同时另设一组专门作用于 .storybook/main.@(js|cjs|mjs|ts) 的规则(见 code/lib/eslint-plugin/src/configs/recommended.ts)。
让 .storybook 目录也被检查:在 .eslintignore 中加入下面一行,作用是撤销对该目录的默认忽略,让插件也能检查 Storybook 自己的配置文件:
!.storybook
官方文档给出的理由是:这样能保证 .storybook 目录内配置始终正确——例如它可以捕捉 [.storybook/main.js|ts] 中拼写错误的 addon 名称(对应规则是 storybook/no-uninstalled-addons)。
4.2 按规则定制(仅对 story 文件生效)
如果你需要覆盖、新增或关闭某条规则,应把这些改动放进 overrides 段,且 files 应与 [.storybook/main.js|ts] 中的 stories 属性保持一致,避免规则被应用到所有文件:
{
"overrides": [
{
// 👇 应与 .storybook/main.js|ts 中的 stories 属性匹配
"files": ["**/*.stories.@(ts|tsx|js|jsx|mjs|cjs)"],
"rules": {
// 👇 开启该规则
"storybook/csf-component": "error",
// 👇 关闭该规则
"storybook/default-exports": "off",
}
}
]
}
4.3 flat config(ESLint v9 默认 / 自 v8.57.0 起可用)
若使用 eslint.config.js(flat config 风格),官方文档提供了两种推荐写法。最简单的是直接展开 flat/recommended:
import storybook from 'eslint-plugin-storybook';
// 若使用更老的 ESLint 版本,可将 eslint/config 替换为 @eslint/config-helpers
import { defineConfig } from 'eslint/config';
export default defineConfig([
...storybook.configs['flat/recommended'],
// 在此追加其他通用配置,如 js.configs.recommended
]);
由于 eslint-plugin-storybook 的主模块默认导出中同时带有 configs、meta 与 rules 三个命名导出(见 code/lib/eslint-plugin/src/index.ts),配置对象会自然被 flat config 注册器识别。
当你使用 tseslint、tslint 等工具的配置辅助函数时,注册方式略有不同——需要把整个插件对象作为参数传入而非解构它:
import storybook from 'eslint-plugin-storybook';
import somePlugin from 'some-plugin';
import tseslint from 'typescript-eslint';
export default tseslint.config(
somePlugin,
storybook.configs['flat/recommended'], // 注意:不要解构
);
同时,flat config 下让 .storybook 参与检查需使用 globalIgnores 反转忽略规则:
import { defineConfig, globalIgnores } from 'eslint/config';
export default defineConfig([
globalIgnores(['!.storybook'], 'Include Storybook Directory'),
// ...
]);
在 flat config 中针对 story 文件覆盖单条规则的方式如下:
import storybook from 'eslint-plugin-storybook';
import { defineConfig } from 'eslint/config';
export default defineConfig([
...storybook.configs['flat/recommended'],
{
// 👇 应与 .storybook/main.js|ts 中的 stories 属性匹配
files: ['**/*.stories.@(ts|tsx|js|jsx|mjs|cjs)'],
rules: {
// 👇 开启该规则
'storybook/csf-component': 'error',
// 👇 关闭该规则
'storybook/default-exports': 'off',
},
},
]);
MDX 兼容性说明:官方文档明确该插件不支持 MDX 文件。若你的 story 写在 .mdx 中,插件规则不会对其生效。
五、内置配置与规则速览
从源码 code/lib/eslint-plugin/src/index.ts 可以确认,插件导出的配置(configs)共 8 种,分为两组:
- 传统 eslintrc 配置:
csf、csf-strict、addon-interactions、recommended; - flat config 配置:
flat/csf、flat/csf-strict、flat/addon-interactions、flat/recommended。
这 4 类规则集的定义文件一一对应,位于 code/lib/eslint-plugin/src/configs 与同目录下的 flat/ 子目录。
插件当前共导出 16 条规则(对应 code/lib/eslint-plugin/src/rules 下的 16 个 *.ts 实现文件)。以官方文档(docs/configure/integration/eslint-plugin.mdx 中的规则总表)为据,典型规则与所属配置如下:
| 规则 | 作用 | 可自动修复 | 所属配置 |
|---|---|---|---|
storybook/await-interactions |
interactions 必须被 await | ✅ | addon-interactions、recommended |
storybook/context-in-play-function |
调用其他 story 的 play function 时应传入上下文 | - | recommended、addon-interactions |
storybook/csf-component |
meta 中应设置 component 属性 | - | csf、csf-strict |
storybook/default-exports |
story 文件应有默认导出 | ✅ | csf、csf-strict、recommended |
storybook/hierarchy-separator |
title 中不应使用已废弃的分层分隔符 | ✅ | csf、csf-strict、recommended |
storybook/no-redundant-story-name |
story 不应有冗余的 name 属性 | ✅ | csf、csf-strict、recommended |
storybook/no-renderer-packages |
story 中不应直接导入 renderer 包 | - | recommended |
storybook/no-stories-of |
storiesOf 已废弃,不应使用 |
- | csf-strict |
storybook/no-title-property-in-meta |
不应在 meta 中定义 title | ✅ | csf-strict |
storybook/no-uninstalled-addons |
识别拼写错误或未安装的 addon | - | recommended(作用于 .storybook/main.*) |
storybook/prefer-pascal-case |
story 命名应使用 PascalCase | ✅ | recommended |
storybook/story-exports |
story 文件至少导出一个 story | - | csf、csf-strict、recommended |
storybook/use-storybook-expect |
应使用 @storybook/test、storybook/test 或 @storybook/jest 的 expect |
✅ | addon-interactions、recommended |
storybook/use-storybook-testing-library |
不要在 story 中直接使用 testing-library | ✅ | addon-interactions、recommended |
(此外还有 storybook/meta-inline-properties、storybook/meta-satisfies-type 两条独立规则,不属于上述任何配置。)
作为对照,从源码 code/lib/eslint-plugin/src/configs/recommended.ts 可以看到 recommended 配置在两个 overrides 段中分别启用的完整规则集合:对 story 文件启用 await-interactions、context-in-play-function、default-exports、hierarchy-separator、no-redundant-story-name、no-renderer-packages、prefer-pascal-case、story-exports、use-storybook-expect、use-storybook-testing-library 等规则,并将 react-hooks/rules-of-hooks、import-x/no-anonymous-default-export 关闭以避免与 story 写法冲突;对 .storybook/main.* 文件则仅启用 no-uninstalled-addons。每条规则的实现与配套测试位于 code/lib/eslint-plugin/src/rules(如 default-exports.ts 与 default-exports.test.ts),如果你需要了解某条规则的判定细节,可以直接查阅对应文件与测试用例。
六、安装与启用后的验证方式
完成上述三步(安装 ESLint → 安装 eslint-plugin-storybook → 在配置中启用 plugin:storybook/recommended 并放行 .storybook 目录)后,你可以在终端直接运行:
npx eslint "**/*.stories.@(ts|tsx|js|jsx|mjs|cjs)"
预期出现两类输出:
- 无输出(退出码 0):所有 story 文件通过检查;
- 报告
storybook/*开头的错误或警告:例如Default export should be placed at the end of the file(default-exports)、Stories should use PascalCase(prefer-pascal-case)等,可按提示逐一修正或按上文「overrides」方式按项目规范调整。
若你新写一个 Button.stories.tsx 却忘记默认导出或写错了 addon 名,插件会立刻给出定位到具体文件的诊断信息——这正是把 lint 接入 CI 或 IDE 后带来的持续保障。
七、小结
接入 eslint-plugin-storybook 的核心路径可以浓缩为四步:安装 ESLint → 按包管理器安装 eslint-plugin-storybook(本文档的三种命令即 eslint-plugin-storybook-install.md 片段的全部内容)→ 在 .eslintrc 或 eslint.config.js 中启用 plugin:storybook/recommended / flat/recommended → 通过 .eslintignore 或 globalIgnores 放行 .storybook 目录。插件会自动限定到 *.stories.* / *.story.* 文件并对 .storybook/main.* 单独启用 addon 检查,无需手工圈定文件范围。安装前后注意核对 ESLint 大版本与插件版本映射,即可让 story 代码在团队中保持一致的、符合 Storybook 最佳实践的质量基线。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0625
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00