Storybook 中生成 MSW Service Worker:为组件 Stories 接入网络请求 Mock 的完整配置指南
Storybook 中生成 MSW Service Worker为组件 Stories 接入网络请求 Mock 的完整配置指南本指南聚焦 Storybook 文档中Mocking network requests模拟网络请求一节的核心前置步骤——通过msw init生成 Mock Service WorkerMSW所需的 Service Worker 文件并结合staticDirs、项目级 loader 与beforeEach({ msw })完成 REST/GraphQL 请求的 Story 级拦截。读完本文你将能在自己的 Storybook 工作区中一键产出可用的mockServiceWorker.js并让 MSW 插件接管组件运行期间发出的真实网络请求。相关配套文档见 mocking-network-requests.mdx本次讲解的命令原文出自 msw-generate-service-worker.md。为什么 Stories 需要先生成一个 Service WorkerMSW 是一套基于 Service Worker 的 API 拦截方案它在浏览器预览环境中注册一个 Service Worker 脚本来捕获 fetch/XHR 请求并返回由请求处理器handler准备的假数据。对于会发起真实网络请求的组件例如从 REST 或 GraphQL API 拉取数据的页面Storybook 里渲染这些组件时既不应该真的打到后端也不应该让故事因网络不可用而失败因此官方文档建议使用 MSW 插件msw-storybook-addon把 Mock 能力带进 Stories。而生成 Service Worker 文件正是这条链路的物质基础只有在项目静态目录中先放置 MSW 运行时脚本浏览器才有可注册的 Worker 去接管后续请求。该文件并非手写而是由 MSW 官方 CLI 的命令msw init 目录一次性产出。也就是说生成 Worker 这一步不是可选项而是使用 MSW 插件在 Storybook 中拦截请求的前置条件。完整接入流程总览围绕本主题官方文档给出了一个可复制的四步流水线安装msw与msw-storybook-addon安装命令见 msw-addon-install.md以 devDependency 形式写入运行msw init生成 Service Worker 文件本文核心命令见 msw-generate-service-worker.md在 Storybook 配置中通过staticDirs把 Worker 所在目录设为静态资源目录配置示例见 main-config-static-dirs.md初始化插件并将其注册到所有 StoriesCSF 3 使用项目级loaders: [mswLoader()]CSF Next 则在definePreview中通过addons: [addonMsw()]注册示例见 msw-addon-initialize.md。后续在编写 Story 时再通过beforeEach({ msw })注入当前 Story 专属的请求处理器。下面按此顺序逐层展开重点是第 2、3 步与命令背后的参数含义。一条命令生成 Service Worker三种包管理器的等价写法原文档针对不同包管理器给出了三份等价命令正文均为npmnpx msw init ./public --saveyarnyarn dlx msw init ./public --savepnpmpnpm dlx msw init ./public --save三者通过不同的包管理器临时执行mswCLI效果一致可根据团队实际使用的包管理器任选其一执行。命令逐段拆解如下参数含义说明initMSW CLI 的子命令用于在指定目录中初始化/生成 Service Worker 脚本./publicWorker 文件的输出目录默认放在项目的public目录最终产出./public/mockServiceWorker.js--save记录配置让 CLI 记住 Worker 输出目录便于后续维护时无需重复指定完整参数执行成功后会生成mockServiceWorker.js——一个体积小、自包含的浏览器端运行时脚本负责在页面与网络之间充当拦截代理。注意该文件不应手工改动它需要与所安装的msw版本保持严格一致当升级msw依赖后通常需要重新执行一次生成命令以更新 Worker 脚本。Angular 项目的目录差异官方特别提醒官方文档在原命令后附加了一条框架相关的提醒Angular 项目很可能需要调整目录参数把 Worker 保存到不同于默认值的位置例如保存到src目录。原因在于 Angular 项目的构建与静态资源组织方式与其他前端脚手架不同Worker 必须放在能被浏览器按预期 URL 访问到的位置。因此 Angular 用户应把命令改写为类似npx msw init ./src --save的形式并同步调整下一步staticDirs的指向。用 staticDirs 把 Worker 暴露给 Storybook 预览仅生成文件还不够。Storybook 的预览运行在一个 iframe 环境中浏览器要能请求到mockServiceWorker.js就必须让该文件所在的目录成为 Storybook 可服务的静态目录。这正是staticDirs的作用。配置位于.storybook/main.js或对应的main.ts中。官方给出的通用配置示例main-config-static-dirs.md默认已将../public纳入静态目录export default { framework: storybook/your-framework, stories: [../src/**/*.mdx, ../src/**/*.stories.(js|jsx|mjs|ts|tsx)], staticDirs: [../public, ../static], };若你生成的 Worker 在默认的public目录默认项目脚手架恰好把它配置为静态目录则无需改动但若像 Angular 那样把 Worker 放到了src就必须把对应目录补进staticDirs并保证这里的相对路径从.storybook/出发能正确解析到 Worker 文件否则插件在注册阶段将无法拉取到 Worker 脚本。初始化插件让所有 Stories 都能访问 Mock 上下文Worker 就位后需要让 Storybook 在渲染每个 Story 前启动 MSW 拦截环境。官方文档给出了两种写法见 msw-addon-initialize.md。CSF 3 时代在.storybook/preview.js或preview.ts中注册项目级 loaderimport { mswLoader } from msw-storybook-addon/csf3; export default { loaders: [mswLoader()], };使用 CSF Next实验性时则在definePreview中把插件声明为 addonimport { definePreview } from storybook/your-framework; import addonMsw from msw-storybook-addon; export default definePreview({ addons: [addonMsw()], });loader 被注册在项目级意味着对项目中所有 Stories 生效每个 Story 渲染前都会准备好msw上下文供我们在 Story 定义中使用见下节。这是把网络 Mock 无缝接入每个组件故事的总开关缺少该步骤则后续beforeEach({ msw })拿不到可用实例。在 Stories 中按需拦截 REST 与 GraphQL 请求完成上述基础设施后即可编写真正拦截网络请求的 Stories。官方文档以 DocumentScreen 为例给出成功与失败两条 Story本文摘录其 REST 版本核心形态完整示例见 msw-addon-configure-handlers-http.mdimport { http, HttpResponse, delay } from msw; import type { Meta, StoryObj } from storybook/your-framework; import { DocumentScreen } from ./YourPage; const meta { component: DocumentScreen, } satisfies Metatypeof DocumentScreen; export default meta; type Story StoryObjtypeof meta; export const MockedSuccess: Story { beforeEach({ msw }) { msw.use( http.get(https://your-restful-endpoint/, () { return HttpResponse.json(TestData); }), ); }, }; export const MockedError: Story { beforeEach({ msw }) { msw.use( http.get(https://your-restful-endpoint, async () { await delay(800); return new HttpResponse(null, { status: 403 }); }), ); }, };要点解读beforeEach({ msw })在每个 Story 渲染前执行msw.use(...)用于追加或覆盖当前请求处理器http.get来自msw核心库HttpResponse.json用于快速返回 JSON Mock 数据delay(800)可模拟真实网络延迟配合new HttpResponse(null, { status: 403 })即可构造加载中—失败的交互时序同一份数据在成功与失败两个 Story 间切换就足以驱动组件把加载态、成功态、错误态三种 UI 完整展示出来这正是组件测试与文档展示中最常用的手法。GraphQL 场景思路一致只是把http.get换成graphql.query(AllInfoQuery, ...)并以{ data: { ... } }或{ errors: [...] }结构返回响应官方同样提供了查询成功与访问被拒两个 Story 的对照写法见 msw-addon-configure-handlers-graphql.md并配套展示了 ReactApollo Client、SvelteURQL、Vue3、Angular 等不同框架下如何为组件提供 Mock 客户端包裹层。处理器的作用域Story 级 / 组件级 / 项目级从官方示例可以观察到一个重要的可伸缩规律beforeEach不只可以写在单个 Story 上还可以提升到不同层级Story 级仅在某个 Story 渲染前注册适合成功/失败这类单点对照组件meta级把beforeEach写在组件导出的meta上该文件内的所有 Stories 共享同一组处理器项目级把注册动作放进preview.js/ts对整个项目的全部 Stories 生效适合全局性的默认 Mock。若使用 CSF 3还可以通过msw参数在 Story/组件/项目三个维度声明处理器官方文档建议参考该页面对应旧版本的内容了解msw参数的具体写法。层级化的注册方式让 Mock 逻辑能够跟随组件规模自然演进避免在大型项目中重复堆叠处理器。版本注意事项面向 MSW addon v3官方文档特别指出上文涉及的命令与代码片段面向MSW 插件 v3。若项目仍在使用 v2其接入方式与 API 有差异需要查阅历史版本页面进行对照。升级到 v3 后可使用社区提供的 codemod 一键迁移配置与 Storiesnpx msw-storybook-migrate该迁移命令的作用是把 v2 时代的旧式写法自动改写为 v3 语法如msw参数迁移为beforeEach({ msw })风格降低升级摩擦。从仓库证据看Storybook 官方文档树以该命令配合 Callout 警告框的方式明确了 v2/v3 的行为边界见 mocking-network-requests.mdx。验证与常见排错路径完成上述配置后可通过以下清单确认链路是否打通文件存在性确认生成命令在预期目录产出了mockServiceWorker.js默认public/下Angular 通常在src/下且未手工改动内容版本一致性升级msw依赖后重新执行一次生成命令避免 Worker 脚本与库版本错配导致静默失效静态目录核对.storybook/main.js中staticDirs确实包含了 Worker 所在目录且路径从.storybook/出发可正确解析全局注册确认.storybook/preview.js里已有loaders: [mswLoader()]CSF 3或definePreview中注册了addonMsw()CSF Next否则 Story 中的msw上下文不可用作用域正确确认目标beforeEach挂在正确的层级Story/meta/project避免出现处理器注册了却未生效的错觉。至此从生成 Service Worker 到 Story 级 REST/GraphQL 拦截的完整闭环已经建立msw init提供拦截运行时staticDirs保证它可被访问mswLoader/addonMsw把 Mock 能力注入每个 Story而beforeEach({ msw })则让你为不同故事精准编排各自的成功、失败与延迟场景。创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Python为何成为编程入门首选:语法、生态与实战优势

Python为何成为编程入门首选:语法、生态与实战优势

1. Python为何持续称霸编程入门领域十年前我刚开始接触编程时,面对C复杂的指针和Java繁琐的配置一度想要放弃。直到遇见Python,才真正体会到编程的乐趣。如今虽然Go、Rust等新语言层出不穷,但每年TIOBE和PYPL排行榜上Python依然稳居前三&…

2026/9/21 5:25:24 阅读更多 →
悬臂梁振动控制:LQR与有限元建模实践

悬臂梁振动控制:LQR与有限元建模实践

1. 项目背景与核心价值悬臂梁作为工程结构中常见的承载形式,其振动控制问题一直是机械工程和自动化领域的重点研究方向。去年我在参与某精密仪器减振项目时,就深刻体会到传统PID控制在处理柔性结构振动时的局限性——当梁体出现高阶模态振动时&#xff0…

2026/9/20 23:53:47 阅读更多 →
Agent Harness 长任务中断?TaoToken 这样改模型 Base URL

Agent Harness 长任务中断?TaoToken 这样改模型 Base URL

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 0:49:14 阅读更多 →

最新新闻

石察卡图解原理:3个核心考点拆解版本升级痛点

石察卡图解原理:3个核心考点拆解版本升级痛点

石察卡图解原理:3个核心考点拆解版本升级痛点 版本升级后 API 全变了,石察卡图解原理能救命。 别再对着报错日志发呆,大厂面试最爱问这个。 用图解原理看透石察卡,面试直接拿高分。 考点梳理:为什么石察卡成为高频面试题…

2026/9/22 2:27:22 阅读更多 →
应的繁体字避坑指南:3步搞定环境配置完整示例

应的繁体字避坑指南:3步搞定环境配置完整示例

应的繁体字避坑指南:3步搞定环境配置完整示例 配置环境就卡半天,这种痛谁懂?很多开发者在搭建项目时,因为一个不起眼的字符编码问题,导致依赖安装失败、构建报错,甚至前端页面出现乱码。今天要解决的核心痛点,就是“应的繁体字”这一类特殊字符在不同…

2026/9/22 2:27:21 阅读更多 →
成都入户性能优化源码解析:3步解决报错堆积

成都入户性能优化源码解析:3步解决报错堆积

成都入户性能优化源码解析:3步解决报错堆积 盯着屏幕上一长串红色的 StackTrace,心里那个慌啊。每一行调用栈都像天书,尤其是当业务逻辑嵌套了七八层,报错信息指向某个陌生的类名时,根本不知道从哪下手。很多刚接触后端开发的兄弟,面对这种…

2026/9/22 2:27:21 阅读更多 →
剑三抓马插件性能优化实战:3个底层原理让你面试不再卡壳

剑三抓马插件性能优化实战:3个底层原理让你面试不再卡壳

剑三抓马插件性能优化实战:3个底层原理让你面试不再卡壳 面试被问原理答不上来,是无数转岗开发者的噩梦。当你还在纠结业务逻辑时,面试官却盯着底层实现追问细节,这种落差感让人窒息。今天不讲虚的,直接拆解【剑三抓马插件】在【性能优化】上的底层逻辑…

2026/9/22 2:27:21 阅读更多 →
文字扫描识别软件面试避坑:3个核心考点助你搞定性能优化

文字扫描识别软件面试避坑:3个核心考点助你搞定性能优化

文字扫描识别软件面试避坑:3个核心考点助你搞定性能优化 很多开发者学了 OCR 基础语法,却卡在“怎么把识别准确率提到 99% 以上”这一步。别慌,这正是面试大厂时最容易被问到的 性能优化…

2026/9/22 2:26:20 阅读更多 →
车架号查询车辆信息实战:5种后端方案对比与最佳实践

车架号查询车辆信息实战:5种后端方案对比与最佳实践

车架号查询车辆信息实战:5种后端方案对比与最佳实践 学会语法却不知怎么搭项目?这是很多开发者从教程走向生产环境时最大的拦路虎。尤其是面对像 车架号查询车辆信息 这种典型的高频业务场景,很多人只会写 SELECT * FROM cars…

2026/9/22 2:26:20 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →