Angular项目:如何通过CLI生成组件时自动生成*.story.ts文件
在Angular中自动生成组件对应的Storybook文件
方法一:扩展Angular官方Component Schematics(推荐,最稳定)
这是Angular CLI官方支持的扩展方式,能无缝集成到现有ng generate工作流中:
创建本地Schematics集合
- 在项目根目录新建
schematics文件夹,初始化npm:mkdir schematics && cd schematics && npm init -y - 安装依赖:
npm install @angular-devkit/schematics-cli @schematics/angular typescript --save-dev - 新建
tsconfig.json配置TypeScript:{ "compilerOptions": { "baseUrl": ".", "lib": ["es2017"], "module": "commonjs", "target": "es6", "sourceMap": true, "strict": true, "skipLibCheck": true } } - 新建
src/collection.json定义Schematics集合:{ "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "component": { "extends": "@schematics/angular/component", "factory": "./component/index#component" } } }
- 在项目根目录新建
编写扩展逻辑
新建src/component/index.ts,在官方组件生成逻辑后追加Story文件生成:import { Rule, SchematicContext, Tree, chain, externalSchematic } from '@angular-devkit/schematics'; export function component(options: any): Rule { return chain([ // 调用官方Component Schematics生成基础文件 externalSchematic('@schematics/angular', 'component', options), // 生成Storybook文件 (tree: Tree) => { const componentName = options.name.split('/').pop()!; const componentPath = options.path ? `${options.path}/${options.name}` : options.name; const className = componentName.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('') + 'Component'; const storyContent = `import { Meta, StoryObj } from '@storybook/angular';
import { ${className} } from './${componentName}.component';
const meta: Meta<${className}> = {
title: 'Components/${componentName}',
component: ${className},
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<${className}>;
export const Primary: Story = {
args: {
// 可添加组件默认输入参数
},
};; tree.create(${componentPath}/${componentName}.component.story.ts`, storyContent);
return tree;
}
]);
}
3. **编译并启用自定义Schematics** - 在`schematics`目录执行编译: ```bash tsc ``` - 修改项目根目录的`angular.json`,指定默认使用自定义Schematics: ```json "cli": { "defaultCollection": "./schematics" } ``` 之后运行`ng generate component my-new-component`,就会自动生成对应的`.story.ts`文件。 --- ### 方法二:使用npm脚本钩子(快速轻量) 如果不想编写Schematics,可通过npm的`post`钩子实现快速生成: 1. **编写生成脚本** 在项目根目录新建`scripts/generate-story.js`: ```javascript const fs = require('fs'); const path = require('path'); // 解析组件路径和名称 const rawArgs = process.env.npm_config_argv; if (!rawArgs) process.exit(0); const args = JSON.parse(rawArgs).original; const componentIndex = args.indexOf('component') + 1; if (componentIndex >= args.length) process.exit(0); const componentName = args[componentIndex]; const componentPath = path.join('src/app', componentName); const className = componentName.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('') + 'Component'; // 生成Story文件内容 const storyContent = `import { Meta, StoryObj } from '@storybook/angular'; import { ${className} } from './${componentName.split('/').pop()}.component'; const meta: Meta<${className}> = { title: 'Components/${componentName}', component: ${className}, tags: ['autodocs'], }; export default meta; type Story = StoryObj<${className}>; export const Primary: Story = { args: { // 可添加默认参数 }, }; `; const storyFilePath = path.join(componentPath, `${componentName.split('/').pop()}.component.story.ts`); if (!fs.existsSync(storyFilePath)) { fs.writeFileSync(storyFilePath, storyContent, 'utf8'); console.log(`✅ Generated Story file: ${storyFilePath}`); }
- 配置npm脚本
修改package.json的scripts字段:
现在每次执行"scripts": { "generate-story": "node scripts/generate-story.js", "postng": "npm run generate-story" }ng generate component后,脚本会自动检测并生成对应的Story文件。
内容的提问来源于stack exchange,提问作者Ryve
相关产品推荐
相关产品推荐

