- 后端
- 前端
- Web框架
- 开发工具
【免费下载链接】redwood
RedwoodGraphQL
本篇技术指南以 RedwoodJS 框架中的 Storybook 集成为核心主题,完整覆盖从yarn rw storybook启动开发服务器,到通过storybook.config.js、storybook.manager.js、storybook.preview.js三个配置文件定制服务器、渲染行为与 UI 主题的完整流程,并结合当前仓库 packages/storybook 的源码实现,深入剖析 RedwoodJS 是如何在 Storybook 中注入 Redwood 运行时(Router、Apollo、Auth、MSW mock)的底层原理。读完本文,你将掌握在 RedwoodJS 项目中以组件优先的方式开发、调试和测试 UI 组件的完整实战方案。
Storybook 在 RedwoodJS 中的定位
Storybook 带来的是一种"前端优先、组件驱动"(frontend-first, component-driven)的开发工作流:通过在隔离环境中单独开发 UI 组件,开发者可以只关注 UI 本身的需求,而不必过早陷入 API 细节之中。
这种隔离开发模式同时让调试变得异常轻松——你不再需要为了复现一个 bug 而启动 dev server、登录用户、逐个展开下拉菜单、反复点击按钮;也不需要为了修改一个弹窗的颜色而渲染整个页面、发起六次 GraphQL 请求。你只需把组件状态编排成一个个 story,在 Storybook 中按需调整、反复验证,甚至可以顺手为它补上测试。
快速启动 Storybook
在 RedwoodJS 项目中启动 Storybook 只需要一条命令:
yarn rw storybookRedwoodJS 的 CLI 会自动完成 Storybook 的安装与配置,随后在本地7910端口启动服务并打开浏览器。
首次运行时的自动配置
根据当前仓库 docs/docs/storybook.md 中描述的最新行为,首次运行yarn rw storybook时,Redwood CLI 会替你完成两件事:
- 安装 Storybook、框架包(framework package)以及全部相关依赖;
- 在
web/.storybook目录下创建配置文件:web/.storybook/main.ts——Storybook 的主配置文件,其中引用了 RedwoodJS 官方的框架包storybook-framework-redwoodjs-vite;web/.storybook/preview-body.html——用于将根节点 div 的id改为redwood-app,这是 Vite 入口文件运行所必需的。
值得注意的是,当前仓库中的 Storybook 集成已经全面转向 Vite 构建:在 preset.ts 中,框架明确指定了@storybook/builder-vite作为 builder、@storybook/react作为 renderer,与生产项目的 Vite 构建保持对齐。
配置 Storybook:三个配置文件
RedwoodJS 为 Storybook 提供了开箱即用的默认配置,它已经处理好了"如何发现 stories、如何配置构建、如何启动 Mock Service Worker"等一系列问题。只有当你需要扩展这些默认行为时,才需要自定义配置。
你可以在项目的web/config目录下添加三个配置文件:
storybook.config.js——配置 Storybook 的服务器(server)storybook.manager.js——配置 Storybook 的UI(manager 界面)storybook.preview.js——配置故事(stories)的渲染方式
如果web/config目录尚不存在,需要先手动创建:
cd redwood-project/web mkdir config touch config/storybook.config.js config/storybook.manager.js config/storybook.preview.js这三个文件都会与 RedwoodJS 的默认配置进行合并(merge),默认配置位于@redwoodjs/testing包中。对应关系如下:
| 项目配置文件 | 合并的 RedwoodJS 默认配置 |
|---|---|
web/config/storybook.config.js | @redwoodjs/testing包中的main.js |
web/config/storybook.manager.js | @redwoodjs/testing包中的manager.js |
web/config/storybook.preview.js | @redwoodjs/testing包中的preview.js |
配置服务器:storybook.config.js
⚠️ 注意:由于
storybook.config.js配置的是 Storybook 服务器,任何改动都需要重启 Storybook才能生效。
虽然理论上你可以在storybook.config.js中配置 Storybook 服务器支持的所有选项,但实际最常用的只有addons:
module.exports = { /** * This line adds all of Storybook's essential addons. * * @see https://storybook.js.org/addons/tag/essentials */ addons: ['@storybook/addon-essentials'], }@storybook/addon-essentials聚合了 Storybook 官方推荐的核心插件(Controls、Actions、Docs 等),是绝大多数项目的标配。
配置渲染方式:storybook.preview.js
当你希望改变所有故事(stories)的渲染方式时,有两个错误的选择:把逻辑塞进实际组件(会污染组件职责),或者在每一个.stories.js文件里重复添加(会很快让人崩溃)。正确的做法是在storybook.preview.js中用decorators统一装饰所有故事。
例如,给所有故事添加外边距,避免组件紧贴画布左上角:
export const decorators = [ (Story) => ( <div style={{ margin: '48px' }}> <Story /> </div> ), ]这种全局装饰器机制与当前仓库的源码实现理念一致:在 preview.tsx 中,RedwoodJS 框架包自身也正是通过注册全局decorators,为每个故事注入StorybookProvider运行时环境的。
配置 UI:storybook.manager.js
⚠️ 注意:对 Storybook UI 的部分改动需要刷新缓存才能生效。最简便的方式是在启动时携带
--no-manager-cache标志:yarn rw storybook --no-manager-cache
一个典型的 UI 定制场景是主题化(theming)。首先,从项目根目录安装两个依赖:
yarn workspace web add -D @storybook/addons @storybook/theming然后创建storybook.manager.js并启用 Storybook 的暗色主题:
import { addons } from '@storybook/addons' import { themes } from '@storybook/theming' addons.setConfig({ theme: themes.dark, })你还可以基于@storybook/theming创建自定义主题,并将主题导出以复用到 Storybook Docs 中。
源码级剖析:RedwoodJS 如何驱动 Storybook
以上配置文档描述的是"用户侧"的操作方式。要真正理解 RedwoodJS 的 Storybook 集成,需要深入当前仓库 packages/storybook/src 的源码,看它在框架层面替你做了什么。这些源码是 Vite 时代的集成实现,也是storybook-framework-redwoodjs-vite框架包的核心。
Vite 配置合并:preset.ts
preset.ts 是框架包的核心预设,它通过viteFinal钩子深度定制 Vite 构建:
// packages/storybook/src/preset.ts(关键片段) export const viteFinal: StorybookConfig['viteFinal'] = async (config) => { const { plugins = [] } = config // Needs to run before the react plugin, so add to the front plugins.unshift(reactDocgen()) plugins.unshift(nodePolyfills()) return mergeConfig(config, { // This is necessary as it otherwise just points to the `web` directory, // but it needs to point to `web/src` root: redwoodProjectPaths.web.src, plugins: [mockRouter(), mockAuth(), autoImports], resolve: { alias: { '~__REDWOOD__USER_ROUTES_FOR_MOCK': redwoodProjectPaths.web.routes, '~__REDWOOD__USER_WEB_SRC': redwoodProjectPaths.web.src, }, }, ... }) }这段代码揭示了几个关键设计:
- 构建根目录指向
web/src:Vite 的 root 被重定向到web/src,而不是整个web目录; - 三个核心插件:
mockRouter()(把@redwoodjs/router替换为 Mock 实现)、mockAuth()(把用户的createAuth替换为测试用 mock)、autoImports(自动导入 mock 工具函数); - 两个路径别名:
~__REDWOOD__USER_ROUTES_FOR_MOCK指向用户的Routes文件,~__REDWOOD__USER_WEB_SRC指向web/src,供 mock 模块按需加载用户源码; reactDocgen()与nodePolyfills():分别用于从组件生成文档类型信息、为浏览器环境补齐 Node polyfill。
全局运行时注入:preview.tsx 与 MockProviders
preview.tsx 注册了框架级的decorators与loaders。其中MockingLoader在 StorybookProvider.tsx 中实现,它做了三件事:
- 通过 Vite 的 Glob Import(
import.meta.glob,并开启eager: true)预加载web/src下所有*.mock.{js,ts}文件,确保任何使用了 Cell 的组件都能拿到 mock 数据; - 调用
startMSW('browsers')启动 Mock Service Worker; - 调用
setupRequestHandlers()注册请求处理器。
随后,StorybookProvider会在每个故事渲染前调用mockCurrentUser(null),默认将当前用户置空,保证每个故事从干净状态开始。
每个故事最终都被包裹在 MockProviders.tsx 提供的完整 Redwood 运行时环境中:
// packages/storybook/src/mocks/MockProviders.tsx(结构示意) <RedwoodProvider titleTemplate="%PageTitle | %AppTitle"> <RedwoodApolloProvider useAuth={useAuth}> <UserRoutes /> <LocationProvider> <MockParamsProvider>{children}</MockParamsProvider> </LocationProvider> </RedwoodApolloProvider> </RedwoodProvider>这意味着你的故事默认就拥有完整的 RedwoodJS 运行时能力:Redwood Provider(页面标题模板)、Apollo GraphQL 客户端、用户Routes中的路由对象(用于routes.xxx())、路由Location上下文,以及 Mock 参数注入——这也是为什么在 Storybook 中你可以直接使用mockGraphQLQuery等工具为 Cell 组件模拟 GraphQL 数据。
自动导入的 mock 工具
auto-imports.ts 通过unplugin-auto-import为所有.ts/.tsx/.js/.jsx文件自动注册了三个来自@redwoodjs/testing/web的全局函数,无需手动 import 即可在 story 中直接使用:
mockGraphQLQuery——模拟 GraphQL Query 响应;mockGraphQLMutation——模拟 GraphQL Mutation 响应;mockCurrentUser——设置当前登录用户。
这与文档中提到的"为 Cell 组件 mock GraphQL 再容易不过"直接对应,也是组件驱动开发体验的关键一环。
Auth 与 Router 的运行时替换
plugins/mock-auth.ts 会在构建期通过正则改写web/src/auth文件:移除原有的createAuth具名导入,改从@redwoodjs/testing/dist/web/mockAuth.js导入createAuthentication as createAuth,从而把真实认证逻辑替换为测试用 mock 实现。
plugins/mock-router.ts 则将源码中所有对'@redwoodjs/router'的导入改写为storybook-framework-redwoodjs-vite/dist/mocks/MockRouter,让routes对象等路由能力在 Storybook 环境中可用(对应 MockRouter.tsx)。
版本演进说明:从 Webpack 到 Vite
值得说明的是,本文所依据的 version-5.x 文档描述的配置方式(web/config下的三个文件与@redwoodjs/testing中的默认配置)属于该版本的集成方案;而当前仓库 packages/storybook 中的实现已演进为基于 Vite 的框架包方案(storybook-framework-redwoodjs-vite),构建产物与生产项目对齐。如果你此前使用的是旧版 Webpack 集成且没有自定义配置,升级后开箱即用体验保持一致;如果存在自定义 Storybook 配置(例如全局 decorators),则需要按新方案迁移:全局 decorators 现在可以直接遵循 Storybook 官方文档中的全局 decorator 方式配置。
无论采用哪个版本,核心的配置心智模型是一致的:Storybook 的服务器配置、UI 配置与渲染配置分离,并且始终与 RedwoodJS 的默认配置合并生效。
总结
RedwoodJS 的 Storybook 集成让"组件驱动开发"成为现实:一条yarn rw storybook命令即可在7910端口获得隔离的组件开发环境;web/config下的三个配置文件分别掌控服务器、渲染与 UI;而框架层源码则默默替你完成了 Redwood 运行时注入、GraphQL mock、认证 mock、路由 mock 与 MSW 启动等全部底层工作。理解这些机制后,你既可以在配置层面按需定制,也能在遇到问题时从源码层面定位原因——这正是高效使用组件驱动工作流的关键。
- 后端
- 前端
- Web框架
- 开发工具
【免费下载链接】redwood
RedwoodGraphQL
相关推荐
RedwoodJS 使用 Storybook 进行组件驱动开发:启动、配置与深度实践指南
RedwoodJS 使用 Storybook 进行组件驱动开发:启动、配置与深度实践指南 导读 Storybook 是 RedwoodJS 官方推荐的组件驱动开
后端前端Web框架开发工具RedwoodJS 组件驱动开发实战:从 Storybook 启动、隔离调试到三层配置扩展
RedwoodJS 组件驱动开发实战:从 Storybook 启动、隔离调试到三层配置扩展 本篇指南围绕 RedwoodJS(当前仓库即 redwood htt
后端前端Web框架开发工具RedwoodJS Storybook 集成指南:基于 Vite 的组件驱动开发工作流
RedwoodJS Storybook 集成指南:基于 Vite 的组件驱动开发工作流 导读 Storybook 是 RedwoodJS 官方支持的组件驱动开发
后端前端Web框架开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考