首页
/ Storybook 全局 Parameters 配置详解:在 .storybook/preview 中定义项目级参数

Storybook 全局 Parameters 配置详解:在 .storybook/preview 中定义项目级参数

2026-09-07 17:47:51作者:余洋婵Anita

本篇围绕 Storybook 仓库中的官方代码片段 parameters-in-preview.md 展开,讲解如何在 .storybook/preview 文件中通过 parameters 导出为所有 story 配置全局元数据。读完本文,你将掌握全局参数的 CSF 3 与 CSF Next(definePreview)两种写法、各框架下的配置差异,并能结合 @storybook/core 源码理解参数在 project、meta、story 三层之间的深合并规则。

什么是全局 Parameters

Parameters 是附在 story 上的一组静态命名元数据,通常用于控制 Storybook 功能与 addon 的行为。它们可以在三个层级指定:

  1. Story 级:定义在 story(具名导出)的 parameters 属性上,只对该 story 生效;
  2. Meta(组件)级:定义在 CSF 文件默认导出(defineMeta/meta)的 parameters 上,对该文件内所有 story 生效;
  3. Project(全局)级:即本文主题,定义在 .storybook/preview.ts|tsx 文件的默认导出中,作用于项目中每一个 story

本文引用的官方文档上下文见 Parameters 指南 的 “Global parameters” 小节与 Parameters API 参考 的 “Project parameters” 小节,两者都内嵌了同一个代码片段。官方指南指出:“设置全局参数是配置 addon 的常见方式。以 backgrounds 为例,它决定了每个 story 可渲染的背景列表。”

配置方式一:CSF 3 写法

CSF 3 下,全局参数通过 preview 文件的默认导出直接声明。原始片段提供了 JS 与 TS 两种版本。

JavaScript(.storybook/preview.js.storybook/preview.jsx):

export default {
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light', value: '#fff' },
        dark: { name: 'Dark', value: '#333' },
      },
    },
  },
};

TypeScript(.storybook/preview.ts.storybook/preview.tsx):

// 将 your-framework 替换为你实际使用的框架,如 react-vite、nextjs、vue3-vite 等
import type { Preview } from '@storybook/your-framework';

const preview: Preview = {
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light', value: '#fff' },
        dark: { name: 'Dark', value: '#333' },
      },
    },
  },
};

export default preview;

TS 版本的关键点在于用对应框架 renderer 包导出的 Preview 类型对 preview 对象做类型标注,这样 parameters 下的键(如 backgrounds)能获得来自 essentials 与已安装 addon 的类型提示。backgrounds.options 中每个条目是一个 { name, value } 对象,name 显示在背景工具栏中,value 是实际应用于画布背景的颜色值或 CSS 选择器。

配置方式二:CSF Next 写法(definePreview)

片段中带有 “CSF Next 🧪” 标签的示例展示的是较新的 definePreview 配置形态,其结构相同,只是把默认导出包装成了 definePreview(...) 调用,可获得更完整的类型推导。片段为四种框架 renderer 分别给出了写法:

React(通用模板,your-framework 替换为 react-vitenextjsnextjs-vite 等):

// 将 your-framework 替换为你实际使用的框架(如 react-vite、nextjs、nextjs-vite)
import { definePreview } from '@storybook/your-framework';

export default definePreview({
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light', value: '#fff' },
        dark: { name: 'Dark', value: '#333' },
      },
    },
  },
});

在仓库中,框架包确实按此约定导出 definePreview。以 react-vite 的入口 为例,其实现是一行再导出:

export { __definePreview as definePreview } from '@storybook/react';

即各框架包(@storybook/react-vite@storybook/vue3-vite 等)统一把核心 @storybook/react 等包中的 __definePreviewdefinePreview 名义暴露给用户。

Vue 3(@storybook/vue3-vite)、Angular(@storybook/angular)、Web Components(@storybook/web-components-vite)的写法与上面完全同构,仅导入来源不同:

import { definePreview } from '@storybook/vue3-vite';

export default definePreview({
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light', value: '#fff' },
        dark: { name: 'Dark', value: '#333' },
      },
    },
  },
});

片段中还保留了与每种 TS 写法一一对应的 JS 版本(.storybook/preview.js),源码中的注释说明了原因:“在同时提供 CSF 3 与 Next 两种示例期间,JS 片段仍然需要保留”,即文档站会为 JS/TS 用户提供可切换的标签页。

全局参数如何被解析:源码视角

全局参数写入 preview 文件后,会在预览端经历两步归一化,均可在 @storybook/core 源码中查证。

第一步:收集 preview 文件导出的字段。composeConfigs 中,所有 annotations 模块(preview 文件、加载的 preset 等)的导出被逐字段合成,其中项目级参数正是调用 combineParameters 完成:

// composeConfigs.ts(L51)
parameters: combineParameters(...getField(moduleExportList, 'parameters')),

第二步:按 “项目 → 组件 → story” 顺序逐 story 合并。prepareStory 中,每个 story 的最终参数由三级 parameters 依次合并得出:

const parameters: Parameters = combineParameters(
  projectAnnotations.parameters,   // 第 1 层:.storybook/preview 中的全局参数
  componentAnnotations.parameters, // 第 2 层:CSF 默认导出(meta)
  storyAnnotations?.parameters     // 第 3 层:story 具名导出
);

可见本文讲解的 preview 级参数处于合并链的最底层,为整个项目提供默认值,之后被 meta 级、story 级参数逐层覆盖。

合并语义:objects 深合并、arrays 整体覆盖

combineParameters 的具体实现在 parameters.ts。其算法可以概括为:

  • 后传入的参数集按键逐项覆盖先前的值,除非新值与旧值都是纯对象(plain object)——此时该键被标记为“需深合并”,最后递归调用自身合并;
  • 数组被视为标量,直接整体替换,不做拼接;
  • undefined 的新值不参与覆盖(“ignores undefined additions”)。

这四条语义与其单元测试 parameters.test.ts 完全一致:

// 同键标量:后者胜出
combineParameters({ a: 'b', c: 'd' }, { e: 'f', a: 'g' }) // => { a: 'g', c: 'd', e: 'f' }
// 子键深合并
combineParameters({ ns: { a: 'b', c: 'd' } }, { ns: { e: 'f', a: 'g' } })
// => { ns: { a: 'g', c: 'd', e: 'f' } }
// 数组按标量处理:整体替换
combineParameters({ ns: { array: [1, 2, 3] } }, { ns: { array: [3, 4, 5] } })
// => { ns: { array: [3, 4, 5] } }
// undefined 不覆盖已有值
combineParameters({ a: 1 }, { a: 2 }, { a: undefined }) // => { a: 2 }

这带来两个实战结论:

  1. 局部微调全局配置是安全的。例如全局定义了 backgrounds.options,某个 story 只重写 backgrounds.gridoptions 会原样保留——这正是官方指南强调的“参数是合并的,键只会被覆盖、不会被丢弃”,也是开发依赖 parameters 的 addon 时必须考虑的行为;
  2. 数组类参数(如 options.order 这类列表)在覆盖层是全量替换而非追加,若想在 story 级“追加”数组项,需要在更具体的层级显式写出完整数组。

同样的合并函数还被 argTypes、controls 推断(inferControls.ts)、CSF 工厂(csf-factories.ts)等模块复用,说明“后者优先的对象深合并”是 Storybook 全项目统一的元数据合并契约,parameters 只是其中最常用的一条。

适用前提与注意事项

  • 本写法适用于当前仓库对应的 Storybook 版本(CSF 3 与 CSF Next 并存期):preview 文件支持 js|jsx|ts|tsx 后缀;CSF Next 的 definePreview 示例在片段中带有实验标签(🧪),意味着它面向“CSF Next”新故事格式,迁移前建议在自己的项目上验证;
  • 各框架包的导入路径不同(@storybook/react-vite@storybook/vue3-vite@storybook/angular@storybook/web-components-vite 等),示例中的 your-framework 占位符需按实际安装框架替换;
  • 全局参数中也有例外项:如 options 参数(storySort 等)按 API 参考 的说明只能在项目级(preview 文件)生效,这恰好印证了 preview 级 parameters 是“整个 Storybook 行为的最终兜底配置位”。

小结

docs/_snippets/parameters-in-preview.md 所承载的官方示例,本质上教的是 Storybook 参数继承链的“最底层”——在 .storybook/preview 中导出 parameters,为全部 story 提供 addon 默认配置(示例以 backgrounds.options 的 Light/Dark 两个背景项为例)。CSF 3 下直接默认导出并(TS 中)标注 Preview 类型即可,CSF Next 下则改用各框架包导出的 definePreview 包装。理解 prepareStory.ts 中的三级 combineParameters 调用与 parameters.ts 的“对象深合并、数组整体覆盖、undefined 不覆盖”规则后,你就能准确预测任意层级参数声明的最终生效值,并据此设计自己的 addon 参数接口。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388