Storybook × Angular:用 Angular Builder(`ng run`)一键构建生产级静态站点
导读
在 Angular 工程中把 Storybook 发布为可供任意 Web 服务器托管的静态站点,最推荐的方式并不是直接执行 storybook build,而是通过 Angular 原生的 Architect Builder——即 @storybook/angular:build-storybook,以 ng run <project>:build-storybook 一行命令驱动构建。本文结合官方文档 docs/sharing/publish-storybook.mdx 中 Angular 专属的构建片段与仓库源码,完整讲解该 Builder 的注册、配置、调用与迁移流程,帮助你掌握在 Angular Workspace 内构建、发布 Storybook 静态产物的标准做法。
为什么 Angular 项目应使用自定义 Builder 构建 Storybook
Storybook 官方发布指南将"构建静态 Web 应用"作为发布第一步,且对绝大多数框架已经内置预配置了构建命令。但对于 Angular 用户,官方文档专门做了差异化建议(发布指南 中的 <If renderer="angular"> 分支):
If you're using Angular, it's often better to use the Angular builder to build Storybook.
原因在于 @storybook/angular 框架本身就是基于 Angular 的 Architect Builder 体系实现的。在 docs/get-started/frameworks/angular.mdx 中明确说明:
The Storybook Angular builder is a way to run Storybook in an Angular workspace. It is a drop-in replacement for running
storybook devandstorybook builddirectly.
也就是说,Angular 场景下,启动开发服务器(start-storybook)与生产构建(build-storybook)都可以纳入 angular.json 的 architect 配置体系,与 Angular 应用自身的 build/test/lint 目标保持一致的 CLI 体验,同时还能继承 Angular 工程的 browserTarget(样式、资源等全局配置)以及内置的 Compodoc 文档生成能力。
第一步:在 angular.json 中注册 Storybook Builder 目标
使用 ng run 之前,必须先在项目 angular.json 的 architect 段注册 storybook 与 build-storybook 两个目标。完整注册示例(手动安装文档):
{
"projects": {
"your-project": {
"architect": {
"storybook": {
"builder": "@storybook/angular:start-storybook",
"options": {
// The path to the storybook config directory
"configDir": ".storybook",
// The build target of your project
"browserTarget": "your-project:build",
// The port you want to start Storybook on
"port": 6006
}
},
"build-storybook": {
"builder": "@storybook/angular:build-storybook",
"options": {
"configDir": ".storybook",
"browserTarget": "your-project:build",
"outputDir": "dist/storybook/your-project"
}
}
}
}
}
}
其中 browserTarget 的取值格式为 project-name:builder:config,一般指向 @angular-devkit/build-angular:browser 构建目标,便于 Storybook 复用 Angular 工程中声明的 styles、assets 等选项。
Builder 名称与仓库中的注册关系
@storybook/angular:build-storybook 并非凭空存在。在框架包中通过 package.json 的 "builders": "builders.json" 字段向外暴露两份 Builder 元数据,见 code/frameworks/angular/builders.json:
{
"builders": {
"build-storybook": {
"implementation": "./dist/builders/build-storybook/index.js",
"schema": "./build-schema.json",
"description": "Build storybook"
},
"start-storybook": {
"implementation": "./dist/builders/start-storybook/index.js",
"schema": "./start-schema.json",
"description": "Start storybook"
}
}
}
构建入口配置位于 code/frameworks/angular/build-config.ts,其中将 ./src/builders/build-storybook/index.ts 与 ./src/builders/start-storybook/index.ts 分别编译为独立 Node 入口,对应 @storybook/angular/builders/build-storybook 与 @storybook/angular/builders/start-storybook 子路径导出。
第二步:执行生产构建
注册完成后,在 Angular 工程根目录执行(这就是关联文档片段中的核心命令):
# Builds Storybook with Angular's custom builder
ng run my-project:build-storybook
命令中的 my-project 需要替换为 angular.json 中实际的项目名,build-storybook 则是上面注册的 architect 目标名。构建完成即产出 Storybook 的静态 Web 应用,可交给任何 Web 服务器托管。
构建产物的默认输出目录定义在 code/frameworks/angular/build-schema.json 中:
"outputDir": {
"type": "string",
"description": "Directory where to store built files.",
"default": "storybook-static"
}
即不指定时输出到项目根目录的 storybook-static 文件夹(可在 builder 的 options 中通过 outputDir 覆盖,如文档示例中的 dist/storybook/your-project)。
对比:普通 CLI 与 Angular Builder
作为对照,非 Angular 框架或直接使用 CLI 时的构建命令是 storybook build(对应 docs/_snippets/build-storybook-production-mode.md 中展示的 npm run build-storybook / pnpm run build-storybook / yarn build-storybook)。而 Angular 专属的"with-builder"写法(docs/_snippets/angular-builder-production.md)则将构建完全交由 Angular CLI 的 Architect 运行时驱动,两者的产物都可用于后续发布。
第三步:收编为 npm scripts
为了沿用 npm run build-storybook 的团队习惯,把 ng run 命令写入 package.json 脚本即可(这正是关联文档第二个代码片段的内容):
{
"scripts": {
"build-storybook": "ng run my-project:build-storybook"
}
}
ng 是 Angular CLI 的可执行文件,需要在项目开发依赖中包含 @angular/cli(框架包的 peerDependencies 要求 >=18.0.0 < 23.0.0)。
从旧式脚本迁移到 Angular Builder
如果你的项目之前是直接调用 start-storybook / build-storybook(或 storybook dev / storybook build),官方提供了两条迁移路径(迁移指南):
自动迁移
npx storybook@latest automigrate
Storybook 会自动检测配置并完成修复。
手动迁移
先按上文在 angular.json 中补上 storybook 与 build-storybook 两个 architect 目标,然后修改 package.json:
{
"scripts": {
- "storybook": "start-storybook -p 6006", // or `storybook dev -p 6006`
- "build-storybook": "build-storybook" // or `storybook build`
+ "storybook": "ng run <project-name>:storybook",
+ "build-storybook": "ng run <project-name>:build-storybook",
}
}
对于多项目 Workspace,每个项目都需要独立的 .storybook 目录(位于各自项目根目录),并分别执行上述注册与迁移;也可以为每个项目依次运行 npx storybook@latest init 自动生成配置,最后用 Storybook Composition 组合多个 Storybook。
迁移时的 Compodoc 说明
compodoc 已内置进 @storybook/angular,无需再单独调用。若旧脚本中显式运行了 compodoc,可一并移除:
{
"scripts": {
- "docs:json": "compodoc -p tsconfig.json -e json -d ./documentation",
- "storybook": "npm run docs:json && start-storybook -p 6006",
- "build-storybook": "npm run docs:json && build-storybook"
+ "storybook": "ng run <project-name>:storybook",
+ "build-storybook": "ng run <project-name>:build-storybook",
}
}
在 build schema 中,compodoc 选项默认值为 true、compodocArgs 默认值为 ["-e", "json"],且 -p(tsconfig 路径)与 -d(workspace 根目录)参数总会自动附加。
Builder 完整配置选项速查
build-storybook Builder 的完整选项定义于 code/frameworks/angular/build-schema.json(该 schema 同时用于 CLI 校验)。核心选项如下:
| 选项 | 默认值 | 说明 |
|---|---|---|
browserTarget |
null |
Angular 构建目标,格式 project-name:builder:config,一般指向 @angular-devkit/build-angular:browser,用于复用 styles、assets 等 |
outputDir |
storybook-static |
构建产物输出目录 |
configDir |
.storybook |
Storybook 配置目录 |
tsConfig |
— | TypeScript 配置文件路径(相对当前 workspace) |
preserveSymlinks |
false |
模块解析是否保留符号链接路径 |
loglevel |
info |
构建日志级别:trace/debug/info/warn/error/silent |
logfile |
— | 指定后将日志写入该文件 |
debugWebpack |
false |
调试 Webpack 配置 |
enableProdMode |
true |
关闭 Angular 开发模式及框架内断言检查 |
quiet |
false |
抑制冗余构建输出 |
docs |
false |
以文档模式构建 Storybook |
test |
false |
构建面向测试优化(去重文档化产物)的静态版本,适用于 CI/大型项目提速 |
compodoc |
true |
构建前执行 Compodoc 生成文档 |
compodocArgs |
["-e", "json"] |
追加的 Compodoc 参数 |
webpackStatsJson / statsJson |
false |
将 Webpack/构建 stats JSON 写入磁盘 |
previewUrl |
— | 禁用默认 Storybook preview,改用自定义 preview |
styles / stylePreprocessorOptions |
— | 注入全局样式 / 预处理选项 |
assets |
[] |
静态资源列表 |
sourceMap |
false |
source map 配置(布尔或对象) |
experimentalZoneless |
— | 实验性 zoneless 变更检测 |
其中 test: true 对应官方文档中为大型项目/CI 场景提供的性能优化方向:默认生产构建会把全部 stories 与文档打包进产物,测试场景下可通过该选项产出更精简的版本。
源码视角:Builder 底层如何驱动 Storybook 构建
从仓库源码可以清晰看到 Angular Builder 与 Storybook 核心构建服务的关系:
- 依赖上,
@storybook/angular同时以 peerDependency 形式依赖@angular-devkit/architect/@angular-devkit/build-angular(Angular 18~22 范围)与storybook,从 code/frameworks/angular/package.json 可见。 - Builder 实现位于
src/builders/目录,其中start-storybook实现(code/frameworks/angular/src/builders/start-storybook/index.ts)通过createBuilder包装出符合 Architect 规范的 Builder,在内部解析browserTarget/tsConfig等选项后,调用storybook/internal/core-server提供的buildDevStandalone等核心服务,并通过 rxjsObservable保持开发服务器持续运行。生产构建build-storybook(对应src/builders/build-storybook/index.ts,其行为有index.spec.ts测试覆盖)则是"drop-in replacement"的另一半——正如官方文档所述,它在内部替代了对storybook build的直接调用。 - 从依赖结构看,该 Builder 依赖
@storybook/builder-webpack5(webpack 5),因此 Angular 框架当前走的是 Webpack 构建链路。
这意味着:只要沿用 Angular 官方文档的注册方式,ng run 命令会经由 @angular-devkit/architect 解析出 @storybook/angular:build-storybook,再由框架内部的 Builder 转交给 Storybook 核心构建服务完成静态站点生成。
构建产物预览与发布
静态站点构建完成后,可以本地预览验证。官方发布指南提供了通用预览命令(docs/_snippets/preview-storybook-production-mode.md):
# npm
npx http-server ./path/to/build
# pnpm
pnpm dlx http-server ./path/to/build
将 ./path/to/build 替换为实际产物目录(未配置 outputDir 时即 storybook-static)。确认无误后,即可把产物托管到任意静态 Web 服务器(Netlify、S3、GitHub Pages 等)进行发布与团队协作评审。需要注意的是,若想进一步了解 Angular 环境下的架构细节与全部 FAQ,可继续阅读 docs/get-started/frameworks/angular.mdx 与 docs/sharing/publish-storybook.mdx。
小结
在 Angular Workspace 中发布 Storybook 的标准姿势是:先在 angular.json 注册 @storybook/angular:build-storybook 目标,再用 ng run <project>:build-storybook 完成静态构建,最后通过 package.json 脚本固化命令。这套流程把 Storybook 完全纳入 Angular Architect 生态,既统一了 CLI 习惯,也通过 browserTarget 无缝继承应用级样式与资源配置,配合内置 Compodoc,是最贴合 Angular 工程的官方推荐方案。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00