Storybook 的 framework 配置详解:在 main.js/ts 中声明框架与传递框架选项
【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook
导读
framework是 Storybook 主配置文件(.storybook/main.js|ts)中必填的顶层配置项,它决定了 Storybook 使用哪套「框架包」来匹配你的技术栈,以及如何把框架相关的选项传给构建器与渲染器。读完本文你将掌握framework的两种写法(字符串简写与对象写法)、options里各框架共享与专属的参数用法、Vite/Webpack 两类构建器生态下的框架选型,以及在 CSF 3 与 CSF Next 两种配置风格下如何落地一份可运行的main.js|ts。
framework是什么、为什么是必填项
在 Storybook 中,「框架(Framework)」是自动为你的技术栈完成 Storybook 预配置的包:它按照你所使用框架(React、Vue 3、Angular、Next.js、Svelte、Web Components……)的工程约定来装配构建器、加载必要依赖并调整配置,从而大幅减少样板代码。Storybook 启动时会先加载框架配置,再加载已有的 addon,使渲染环境与应用环境保持一致(参见 Frameworks 集成文档)。
因此在主配置中,framework与stories一起被标记为Required。主配置对象里还有addons、core、features、typescript、viteFinal、webpackFinal等可选字段,完整清单见 main-config 概览。
其类型定义如下:
framework: FrameworkName | { name: FrameworkName; options?: FrameworkOptions }- 字符串形式:
framework: '@storybook/react-vite',即简单声明用哪个框架; - 对象形式:
{ name: FrameworkName, options: FrameworkOptions },即声明框架的同时,向框架包传入一套框架专属的options。
在 CSF 3 风格下配置 framework
CSF 3 是当前最通用的 Component Story Format 写法。.storybook/main.js(ESM)中典型的框架配置长这样:
export default { framework: { // Replace react-vite with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc. name: '@storybook/your-framework', options: { legacyRootApi: true, }, }, stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], };若使用 TypeScript 编写配置,可从@storybook/<your-framework>包导入StorybookConfig类型获得类型检查与自动补全:
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc. import type { StorybookConfig } from '@storybook/your-framework'; const config: StorybookConfig = { framework: { name: '@storybook/your-framework', options: { legacyRootApi: true, }, }, stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], }; export default config;注意:主配置文件必须是合法的 ESM——即使用import而非require,同时不能用__dirname/__filename(见 main-config 概览)。如果你不需要传任何框架选项,framework也可以直接简写为包名字符串,如framework: '@storybook/react-vite',典型的完整配置示例可参考 main-config-typical.md。
在 CSF Next 中通过 defineMain 配置 framework
CSF Next 是 Storybook 正在迭代的新一代配置/故事 API(目前为preview状态,仅在 React、Vue、Angular、Web Components 项目中受支持)。在 CSF Next 中,主配置改由类型安全的defineMain工厂函数描述,该函数会为你的项目自动推断类型(详见 CSF Next 文档)。
下面是 React 项目的 CSF Next 写法,注意defineMain从@storybook/<framework>/node子路径导入:
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite) import { defineMain } from '@storybook/your-framework/node'; export default defineMain({ framework: { name: '@storybook/your-framework', options: { legacyRootApi: true, }, }, stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], });对应 JavaScript 版本:
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite) import { defineMain } from '@storybook/your-framework/node'; export default defineMain({ framework: { name: '@storybook/your-framework', options: { legacyRootApi: true, }, }, stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], });各渲染器在 CSF Next 下的具体框架包名
在 CSF Next 中,不同渲染器的框架包名与导入路径如下(.storybook/main.ts):
import { defineMain } from '@storybook/vue3-vite/node'; export default defineMain({ framework: { name: '@storybook/vue3-vite', options: {}, }, stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], });import { defineMain } from '@storybook/angular/node'; export default defineMain({ framework: { name: '@storybook/angular', options: {}, }, stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], });import { defineMain } from '@storybook/web-components-vite/node'; export default defineMain({ framework: { name: '@storybook/web-components-vite', options: {}, }, stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], });import { defineMain } from '@storybook/web-components-vite/node'; export default defineMain({ framework: { name: '@storybook/web-components-vite', options: {}, }, stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], });这些defineMain写法对应的storiesglob 与 CSF 3 完全一致,迁移时配置主体无需改动,只需把导出对象包进defineMain({ ... })即可(可参见 csf-next.mdx 中的迁移 diff)。
framework.name:选择与你技术栈匹配的框架包
name的类型为string。可用框架与对应包名主要按构建器划分(完整清单见 Frameworks 集成文档):
| 构建器 | 框架包 |
|---|---|
| Webpack | React、Angular、Vue 3、Web Components、NextJS、HTML、Ember、Preact、Svelte(如@storybook/react-webpack5、@storybook/nextjs、@storybook/angular) |
| Vite | React、Vue 3、Web Components、HTML、Svelte、SvelteKit、Qwik、Solid(如@storybook/react-vite、@storybook/vue3-vite、@storybook/sveltekit) |
在仓库源码中可以看到每个框架包都会定义自己的FrameworkName常量,例如 React + Vite 框架的FrameworkName限定为'@storybook/react-vite'(见 react-vite/src/types.ts),从而保证主配置里name的字符串不会被轻易写错。实际落地时请使用npx storybook init探测到的框架包名(如react-vite、nextjs、nextjs-vite),或在安装/集成指南中确认,例如 react-vite-add-framework.md、vue3-vite-add-framework.md、angular-add-framework.md、web-components-vite-add-framework.md、nextjs-add-framework.md。
framework.options:向框架包传递专属配置
options的类型为Record<string, any>,即每个框架包都可以定义自己的选项。绝大部分选项是某个框架专属的,但也有少数选项在多个框架间共享——典型例子是那些用于配置 Storybook 构建器的选项。
共享选项:options.builder
builder的类型为Record<string, any>,用于直接配置 Storybook 的底层构建器,即Vite或Webpack。在framework.options下配置构建器是当前(新版 Framework API 下)推荐的做法——当 core.builder 中的说明一致:只有在需要配置「不属于任何框架的构建器」时,才应退回到core.builder.options去配置。也就是说,core里的builder字段正在逐步让位于这里的framework.options.builder。
部分框架的 options 速查
结合 Frameworks 集成文档 中的参数表,常用框架选项汇总如下:
| 选项 | 说明 | 适用框架 |
|---|---|---|
nextConfigPath | 设置 Next.js 配置文件路径framework: { name: '@storybook/nextjs', options: { nextConfigPath: '../next.config.js' } } | NextJS |
builder | 配置 NextJS 的 Webpack 5 构建器选项core: { builder: { name: 'webpack5', options: { lazyCompilation: true } } } | NextJS |
strictMode | 启用 React 的 Strict Modeframework: { name: '@storybook/react-webpack5', options: { strictMode: false } } | React |
legacyRootApi | 需要 React 18。切换是否使用 React 旧版 root API 来挂载组件(便于从 React 17 逐步迁移到 18)framework: { name: '@storybook/react-webpack5', options: { legacyRootApi: true } } | React |
enableIvy | Angular 9+ 默认启用,用 Ivy 编译器替代默认编译器framework: { name: '@storybook/angular', options: { enableIvy: true } } | Angular |
enableNgcc | Angular 9+ 默认启用,为向后兼容而加入 ngcc 支持framework: { name: '@storybook/angular', options: { enableNgcc: false } } | Angular |
源码中的类型佐证
从框架包的类型定义中可以印证 options 的「框架专属」本质。以 React + Vite 为例,其FrameworkOptions只暴露了三个字段(见 react-vite/src/types.ts):
export type FrameworkOptions = { builder?: BuilderOptions; strictMode?: boolean; /** @default false */ legacyRootApi?: boolean; };也就是说,同一个options对象交给不同的框架包,能识别的键是不同的——legacyRootApi只对 React 类框架(react-vite、react-webpack5等)有意义,Angular 框架关心的是enableIvy/enableNgcc,Next.js 框架则额外提供nextConfigPath。其它框架的 options 定义可对照阅读 angular/src/types.ts、nextjs/src/types.ts、vue3-vite/src/types.ts、web-components-vite/src/types.ts 等。这也解释了为什么options的类型被宽泛地定义为Record<string, any>——框架包各自负责解析自己关心的字段。
实用建议与注意事项
- 什么时候用对象写法?只要需要传框架选项(如上面的
legacyRootApi、strictMode),就必须写成{ name, options }对象;没有任何选项时可退化为字符串简写,例如framework: '@storybook/react-vite'。 - CSF Next 与 CSF 3 不要混写:
defineMain是 CSF Next 特有的写法;在同一份主配置中应统一使用一种风格。从 CSF 3 迁移到 CSF Next 时,配置主体(framework、stories、addons)保持不变,只需改用defineMain包裹并调整 import(迁移步骤见 csf-next.mdx)。 - 构建器配置优先走
framework.options.builder:它是新版 Framework API 下的推荐位置,比旧的core.builder.options优先级更高、语义更清晰;仅当你的构建器不属于任何框架时才需要回到core.builder(参见 core 配置参考)。 - 框架名称必须与安装的框架包一致:
@storybook/your-framework只是文档占位符,请替换为storybook init实际生成或框架接入指南中给出的包名(参考 frameworks.mdx 与 RELEASING.md 中所列框架矩阵)。 - 配置文件必须是 ESM:
.storybook/main.js|ts中请使用import/export default,避免使用require、__dirname与__filename,这是主配置能正确加载的前提。
【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考