资讯动态

Storybook Addon API 从零导入:正确区分 storybook/preview-api 与 storybook/manager-api

发布时间:2026/9/10 14:35:08 来源:尧图企业网站定制
Storybook Addon API 从零导入正确区分 storybook/preview-api 与 storybook/manager-api【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook本文是一份针对 Storybook Addon 开发者的入门指南核心讲解 Addon 开发时最基础也最关键的一步——如何正确 import 官方 Addon API 所需的模块。通过一个最小导入示例带你厘清storybook/preview-api控制与配置 Addon 行为和storybook/manager-api读写 Storybook 管理器 UI 与全局 API各自的能力边界、背后的源码实现与真实使用场景读完即可在自己的 Addon 工程里写出正确的导入语句。从一段核心导入代码说起Storybook 允许开发者以编程方式与 Storybook 交互从而构建和分发自定义 Addon 以及其它增强 Storybook 能力的工具。这段能力被官方称为Addon API而使用它的第一步就是在 Addon 源码顶部完成模块导入。在 Storybook 官方文档 docs/addons/addons-api.mdx 的 Core Addon API核心 Addon API一节中导入被定义成下面这样一段最小示例原文见 docs/_snippets/storybook-addons-api-imports.mdimport { addons } from storybook/preview-api; import { useStorybookApi } from storybook/manager-api;示例同时照顾了 JS 与 TypeScript 两种写法manager.js|ts并适用于任意前端框架renderercommon。整体含义很明确Addon 的管理器端代码同时运行在 Storybook 的 manager 与 preview 两个运行环境里因此需要分别从两个不同的子路径取得 API。两个入口包的分工manager-api 与 preview-api依据 docs/addons/addons-api.mdx 第 9–16 行的官方定义Storybook 的 API 通过两个不同的包暴露且目的各不相同导入路径用途storybook/preview-api用于控制并配置 Addon 自身的行为如注册 UI 组件、通信频道、装饰器storybook/manager-api用于与 Storybook 的 manager UI 交互或访问 Storybook APIstorybook/preview-api面向Addon 的注册逻辑与行为定义比如调用addons.add()注册面板/工具栏/标签页调用addons.register()作为 Addon 的入口点使用addons.getChannel()获取与 preview 通信的频道实例。storybook/manager-api面向Addon UI 组件内运行时状态读写典型如useStorybookApi()hook——它让你在 React 组件内完整访问 Storybook API 的方法选中故事、操作 query 参数、打开编辑器等。把上例翻译成实际场景Addon 的register代码通常导入并调用addons来自preview-api而 Addon 渲染出来的面板/工具栏 React 组件则通过useStorybookApi来自manager-api驱动 UI 与状态。为什么两个 import 缺一不可从官方 API 文档可以确认一组相互呼应的能力矩阵preview-api的addons提供addons.add()注册 UI 组件类型、addons.register()Addon 入口点可拿到 StorybookAPI 实例、addons.getChannel()获取与 manager/preview 双向通信的频道、addons.setConfig()覆盖默认 UI 配置如主题、侧边栏尺寸、makeDecorator()以官方 Addon 风格创建装饰器。manager-api提供一组 React hooksuseStorybookApi、useStorybookState、useChannel、useAddonState、useParameter、useGlobals、useArgs等均为上述 API 在组件层的薄封装能显著减少样板代码。因此一个功能完整的 Addon 通常两个包都会用到这正是导入片段里两行 import 并列存在的原因。源码级验证两个子路径导出什么storybook/preview-api的导出实现在 monorepo 中storybook包的导出映射定义于 code/core/package.json第 231–246 行它把两个公共子路径分别指向独立的入口源码./manager-api: { types: ./dist/manager-api/index.d.ts, code: ./src/manager-api/index.ts, default: ./dist/manager-api/index.js }, ./preview-api: { types: ./dist/preview-api/index.d.ts, code: ./src/preview-api/index.ts, default: ./dist/preview-api/index.js }也就是说你写的import { addons } from storybook/preview-api最终会命中 code/core/src/preview-api/index.ts。该文件集中 re-export 了 Addon 相关的核心能力节选export { addons, mockChannel } from ./addons.ts既导出单例addons也导出测试用的mockChannelexport { makeDecorator } from ./addons.ts官方风格的装饰器工厂其它与 Addon 无强关联的运行时导出则来自preview-web、store等模块如DocsContext、StoryStore。而addons单例的来源在 code/core/src/preview-api/modules/addons/main.ts该文件注释明确写着 Enforce addons store to be a singleton强制 addons store 为单例并以export const addons getAddonsStore()导出。这从源码层面印证了无论 Addon 被加载多少次addons.register()等都作用于同一个全局 store。storybook/manager-api的 hooks 实现storybook/manager-api对应 code/core/src/manager-api/index.ts其中export * from ./root.tsx暴露了组件层 hooks 的实际实现。查看 code/core/src/manager-api/root.tsx 可以看到这些 hooks 都是围绕useStorybookApi()构建的useStorybookApi()返回完整 API 对象第 331 行useChannel(eventMap, deps)订阅事件并返回 emitter第 363 行useParameterS(parameterKey, defaultValue?)读取当前故事的参数未定义时回落到默认值第 380 行useAddonStateS(addonId, defaultState?)为指定 Addon 提供持久化状态第 492 行useArgs()读取 / 更新故事 args第 496 行useGlobals()读写全局变量 globals第 515 行。这些实现细节解释了为什么文档推荐从manager-api导入 hooks官方文档docs/addons/addons-api.mdx 第 210 行明确说明 hooks 是storybook/manager-api模块的延伸。实战导入之后能做什么导入语句只是起点。在 docs/addons/addons-api.mdx 中这段导入 snippet 被放在 Core Addon API 章节的段首紧接着展开的是一系列可直接组合进你 Addon 的用法。下面给出与上述两个 import 一一对应的最小实战模式。用addons注册 Addon 面板// my-addon/src/manager.js|ts —— Addon 入口 import { addons } from storybook/preview-api; import { useStorybookApi } from storybook/manager-api; // 1) 通过 register 注册 Addon 并拿到 StorybookAPI addons.register(my-addon, (api) { // 2) 注册 UI 组件类型panel / toolbar / tab 之一 addons.add(my-addon/panel, { type: panel, title: My Addon, render: ({ active }) { // 3) 在组件内部使用 manager-api 的 hook 读取当前故事 const sbApi useStorybookApi(); const story sbApi.getCurrentStoryData(); return active ? pre{JSON.stringify(story, null, 2)}/pre : null; }, }); });其中关键点与参数均可对照 docs/addons/addons-api.mdx 第 18–32 行addons.add(type, { title, render })type为要注册的 UI 组件类型title将显示在 Addon 面板中render是渲染 Addon UI 的函数render会被传入active当面板处于聚焦状态时active为true。addons.register(id, callback)作为所有 Addon 的入口点回调会收到 StorybookAPI 实例后续api.selectStory()、api.setQueryParams()、api.openInEditor()等方法都从它而来。若需与 preview 通信可在注册代码里通过addons.getChannel()拿到兼容 NodeJSEventEmitter的频道实例用emit发事件、用on收事件。用 hooks 增强 Addon 组件若你的 Addon 依赖 Storybook 全局状态globals官方文档推荐这样组合见 docs/addons/addons-api.mdx 第 244–254 行与useGlobals/useArgs相关片段import { useGlobals } from storybook/manager-api; function LocaleToolbar() { const [globals, updateGlobals] useGlobals(); return ( select value{globals.locale} onChange{(e) updateGlobals({ locale: e.target.value })} option valueenEnglish/option option valuezh中文/option /select ); }由于useStorybookState/useGlobals等 hook 会订阅 Storybook 内部状态官方建议配合React.memo、useMemo、useCallback使用避免因高频 re-render 拖慢 UIdocs/addons/addons-api.mdx 第 214、246 行——这与上面看到的useStorybookApi订阅式实现是直接相关的。常见误区与判断准则结合源码与官方文档可以总结出几条实用的判断准则帮助你在写 import 时快速决策要在 Addon 入口/注册处做注册、挂接、通信这类事→ 从storybook/preview-api导入addons、makeDecorator、getChannel等 API。要在组件渲染中读取 API、参数、全局状态并驱动 UI→ 从storybook/manager-api导入useStorybookApi、useParameter、useGlobals、useAddonState等 hooks。不要在 Addon 源码中把两个包混成同一个 import它们由 code/core/package.json 定义为两个独立的子路径导出分别映射到 code/core/src/preview-api/index.ts 与 code/core/src/manager-api/index.ts 两份入口。测试场景preview-api额外导出了mockChannel源码见 code/core/src/preview-api/index.ts为需要在单测中模拟频道的 Addon 提供了便利。延伸阅读本文对应的导入片段只是入口完整的能力清单与逐方法说明可继续阅读仓库内以下文件docs/addons/addons-api.mdxAddon API 完整参考涵盖addons.add()、register()、getChannel()、makeDecorator()、Storybook API 各方法与全部 hooks以及与 Addon 类型docs/addons/addon-types.mdx、编写指南docs/addons/writing-addons.mdx的互链入口code/core/src/preview-api/modules/addons/main.tsaddons单例 store 的实现code/core/src/manager-api/root.tsxmanager-api 各 hooksuseStorybookApi、useChannel、useAddonState、useGlobals、useArgs等的具体实现code/core/package.json./preview-api与./manager-api两个子路径的导出映射定义。掌握storybook/preview-api与storybook/manager-api的导入分工就掌握了 Storybook Addon 开发的第一块基石——无论你接下来要写面板、工具栏、标签页还是装饰器所有 API 都从这一行 import 开始。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价