Angular 版 Storybook
Angular 版 Storybook 是一个框架,可以轻松地为 Angular 应用开发和隔离测试 UI 组件。它包括
- 🧱 使用 Angular 构建器
- 🎛️ 集成 Compodoc
- 💫 还有更多!
要求
- Angular ≥ 18.0 < 20.0
- Webpack ≥ 5.0
开始使用
在没有 Storybook 的项目中
在你的 Angular 项目根目录运行此命令后,按照提示进行操作
npm create storybook@latest
在已有 Storybook 的项目中
此框架设计用于 Storybook 7+ 版本。如果你尚未使用 v7,请运行此命令进行升级
npx storybook@next upgrade
自动迁移
运行上面的 upgrade
命令时,你应该会收到一个提示,要求迁移到 @storybook/angular
,它应该能为你处理好一切。如果自动迁移对你的项目无效,请参考下面的手动迁移。
手动迁移
首先,安装框架
npm install --save-dev @storybook/angular
然后,更新你的 .storybook/main.js|ts
以更改 framework 属性
import { StorybookConfig } from '@storybook/angular';
const config: StorybookConfig = {
// ...
framework: '@storybook/angular', // 👈 Add this
};
export default config;
最后,更新你的 angular.json
以包含 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
// More options available, documented here:
// https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/start-storybook/schema.json
}
},
"build-storybook": {
"builder": "@storybook/angular:build-storybook",
"options": {
"configDir": ".storybook",
"browserTarget": "your-project:build",
"outputDir": "dist/storybook/your-project"
// More options available, documented here:
// https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/build-storybook/schema.json
}
}
}
}
}
}
运行 Storybook
要为特定项目运行 Storybook,请运行以下命令
ng run <your-project>:storybook
要构建 Storybook,请运行
ng run <your-project>:build-storybook
你将在配置的 outputDir
中找到输出(默认为 dist/storybook/<你的项目名>
)。
设置 Compodoc
你可以在组件、指令和 Angular 代码的其他部分上方添加 JSDoc 注释,以便为这些元素提供文档。Compodoc 使用这些注释为你的应用生成文档。在 Storybook 中,在 @Inputs
和 @Outputs
上方添加解释性注释非常有用,因为这些是 Storybook 在用户界面中显示的主要元素。@Inputs
和 @Outputs
是你可以在 Storybook 中与之交互的元素,例如控件。
自动设置
通过 npx storybook@latest init
安装 Storybook 时,你可以自动设置 Compodoc。
手动设置
如果你已经安装了 Storybook,可以手动设置 Compodoc。
安装以下依赖
npm install --save-dev @compodoc/compodoc
将以下选项添加到你的 Storybook Builder 中
{
"projects": {
"your-project": {
"architect": {
"storybook": {
"builder": "@storybook/angular:start-storybook",
"options": {
// 👇 Add these
"compodoc": true,
"compodocArgs": [
"-e",
"json",
"-d",
// Where to store the generated documentation. It's usually the root of your Angular project. It's not necessarily the root of your Angular Workspace!
"."
],
}
},
"build-storybook": {
"builder": "@storybook/angular:build-storybook",
"options": {
// 👇 Add these
"compodoc": true,
"compodocArgs": [
"-e",
"json",
"-d",
"."
],
}
}
}
}
}
}
转到你的 .storybook/preview.ts
并添加以下内容
import type { Preview } from '@storybook/angular';
// 👇 Add these
import { setCompodocJson } from '@storybook/addon-docs/angular';
import docJson from '../documentation.json';
setCompodocJson(docJson);
const preview: Preview = {};
export default preview;
applicationConfig
装饰器
如果你的组件依赖于应用范围的提供者,例如由 BrowserAnimationsModule
或任何其他使用 forRoot 模式提供 ModuleWithProviders
的模块定义的提供者,你可以将 applicationConfig
装饰器应用于该组件的所有故事。这将为它们提供 bootstrapApplication 函数,用于在 Storybook 中引导组件。
import { Meta, applicationConfig, StoryObj } from '@storybook/angular';
import { BrowserAnimationsModule, provideAnimations } from '@angular/platform-browser/animations';
import { importProvidersFrom } from '@angular/core';
import { ChipsModule } from './angular-src/chips.module';
const meta: Meta<ChipsModule> = {
component: ChipsModule,
decorators: [
// Apply application config to all stories
applicationConfig({
// List of providers and environment providers that should be available to the root component and all its children.
providers: [
...
// Import application-wide providers from a module
importProvidersFrom(BrowserAnimationsModule)
// Or use provide-style functions if available instead, e.g.
provideAnimations()
],
}),
],
};
export default meta;
type Story = StoryObj<ChipsModule>;
export const WithCustomApplicationProvider: Story = {
render: () => ({
// Apply application config to a specific story
applicationConfig: {
// The providers will be merged with the ones defined in the applicationConfig decorator's providers array of the global meta object
providers: [...],
}
})
}
moduleMetadata
装饰器
如果你的组件依赖于其他 Angular 指令或模块,可以通过 moduleMetadata
装饰器为组件的所有故事或单独故事提供这些依赖。
import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
import { YourComponent } from './your.component';
const meta: Meta<YourComponent> = {
component: YourComponent,
decorators: [
// Apply metadata to all stories
moduleMetadata({
// import necessary ngModules or standalone components
imports: [...],
// declare components that are used in the template
declarations: [...],
// List of providers that should be available to the root component and all its children.
providers: [...],
}),
],
};
export default meta;
type Story = StoryObj<YourComponent>;
export const Base: Story = {};
export const WithCustomProvider: Story = {
decorators: [
// Apply metadata to a specific story
moduleMetadata({
imports: [...],
declarations: [...],
providers: [...],
}),
],
};
常见问题
如何迁移到 Angular Storybook 构建器?
Storybook 的 Angular 构建器是在 Angular workspace 中运行 Storybook 的一种方式。它可以直接替代运行 storybook dev
和 storybook build
。
你可以运行 npx storybook@next automigrate
尝试让 Storybook 检测并自动修复你的配置。否则,你可以按照接下来的步骤手动调整配置。
你的 workspace 中只有一个 Angular 项目吗?
首先,打开你的 angular.json
,并在项目的 architect
部分添加 storybook
和 build-storybook
条目,如上所示。
其次,调整你的 package.json
脚本部分。通常它看起来像这样
{
"scripts": {
"storybook": "start-storybook -p 6006", // or `storybook dev -p 6006`
"build-storybook": "build-storybook" // or `storybook build`
}
}
现在,你可以使用 ng run <你的项目名>:storybook
运行 Storybook,并使用 ng run <你的项目名>:build-storybook
构建它。相应地调整 package.json
中的脚本。
{
"scripts": {
"storybook": "ng run <project-name>:storybook",
"build-storybook": "ng run <project-name>:build-storybook"
}
}
此外,compodoc
现在已内置到 @storybook/angular
中;你无需显式调用它。如果我们在 package.json
脚本中像这样运行 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"
}
}
将其更改为
{
"scripts": {
"storybook": "ng run <project-name>:storybook",
"build-storybook": "ng run <project-name>:build-storybook"
}
}
我的 Angular workspace 中有多个项目
在这种情况下,你必须按照上述说明为每个要使用 Storybook 的项目调整 angular.json
和 package.json
。请注意,每个项目应在其根目录下有一个专门的 .storybook
文件夹。
你可以为每个项目依次运行 npx storybook@latest init
,以便为它们各自设置 Storybook,自动创建 .storybook
文件夹,并在 angular.json
中创建必要的配置。
然后,你可以使用Storybook 组合来合并多个 Storybook。
如何为 Storybook 配置 Angular 的构建器?
这些是 Angular 构建器可能需要的常用选项
配置元素 | 描述 |
---|---|
"browserTarget" | 使用以下格式提供构建目标。"example-project:builder:config" |
"debugWebpack" | 调试 Webpack 配置"debugWebpack": true |
"tsConfig" | TypeScript 配置文件相对于当前 workspace 的位置。"tsConfig": "./tsconfig.json" . |
"preserveSymlinks" | 解析模块时不使用真实路径。如果为 true,则符号链接被解析为其真实路径;否则,它们被解析为其符号链接路径。"preserveSymlinks": true |
"port" | Storybook 使用的端口。"port": 6006 |
"host" | 为 Storybook 设置自定义 host。"host": "http://my-custom-host" |
"configDir" | Storybook 配置目录位置。"configDir": ".storybook" |
"https" | 启用 HTTPS 启动 Storybook。"https": true 需要自定义证书信息。 |
"sslCa" | 提供 SSL 证书颁发机构。"sslCa": "你的自定义证书颁发机构" 可与 "https" 配合使用(可选) |
"sslCert" | 提供 SSL 证书。"sslCert": "你的自定义证书" https 必需 |
"sslKey" | 提供用于服务 Storybook 的 SSL 密钥。"sslKey": "你的 ssl 密钥" |
"smokeTest" | 成功启动后退出 Storybook。"smokeTest": true |
"ci" | 在 CI 模式下启动 Storybook(跳过交互式提示,不会打开浏览器窗口)。"ci": true |
"open" | 是否在浏览器中自动打开 Storybook。"open": true |
"quiet" | 过滤 Storybook 的详细构建输出。"quiet": true |
"enableProdMode" | 禁用 Angular 的开发模式,这会关闭框架内的断言和其他检查。"enableProdMode": true |
"docs" | 在文档模式下启动 Storybook。"docs": true |
"compodoc" | 之前执行 compodoc。"compodoc": true |
"compodocArgs" | Compodoc 选项。总是会给出包含 tsconfig 路径的 -p 选项和包含 workspace 根目录的 -d 选项。"compodocArgs": ["-e", "json"] |
"styles" | 提供与 Storybook 一起使用的应用程序样式的位置。"styles": ["src/styles.css", "src/styles.scss"] |
"stylePreprocessorOptions" | 为解析到 workspace 根目录的样式预处理器提供进一步的自定义。"stylePreprocessorOptions": { "includePaths": ["src/styles"] } |
"assets" | 静态应用程序资产列表。"assets": ["src/assets"] |
"initialPath" | 首次访问 Storybook 时要附加的 URL 路径。"initialPath": "docs/configure-your-project--docs" |
"webpackStatsJson" | 将 Webpack Stats JSON 写入磁盘。"webpackStatsJson": true |
"previewUrl" | 禁用默认的 Storybook 预览,并允许你使用自己的预览。"previewUrl": "iframe.html" |
"loglevel" | 控制构建期间的日志级别。可以是以下之一:[silly, verbose, info (默认), warn, error, silent]。"loglevel": "info" |
"sourceMap" | 配置源代码映射。"sourceMap": true |
完整的选项列表可以在 Angular builder schema 中找到
API
选项
如果需要,可以传递一个 options 对象进行额外配置
import type { StorybookConfig } from '@storybook/angular';
const config: StorybookConfig = {
framework: {
name: '@storybook/angular',
options: {
// ...
},
},
};
可用的选项有
builder
类型:Record<string, any>
配置框架的构建器的选项。对于此框架,可用选项可在Webpack 构建器文档中找到。