Nx 生成器生成器
为 TypeScript 项目添加 Nx Generator,帮助自动化重复任务,如组件脚手架或强制特定项目结构。
使用方法
生成生成器
有两种方式生成生成器:
- 安装 Nx Console VSCode Plugin 如果您尚未安装
- 在VSCode中打开Nx控制台
- 点击
Generate (UI)
在"Common Nx Commands"部分 - 搜索
@aws/nx-plugin - ts#nx-generator
- 填写必需参数
- 点击
Generate
pnpm nx g @aws/nx-plugin:ts#nx-generator
yarn nx g @aws/nx-plugin:ts#nx-generator
npx nx g @aws/nx-plugin:ts#nx-generator
bunx nx g @aws/nx-plugin:ts#nx-generator
您还可以执行试运行以查看哪些文件会被更改
pnpm nx g @aws/nx-plugin:ts#nx-generator --dry-run
yarn nx g @aws/nx-plugin:ts#nx-generator --dry-run
npx nx g @aws/nx-plugin:ts#nx-generator --dry-run
bunx nx g @aws/nx-plugin:ts#nx-generator --dry-run
选项
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
pluginProject 必需 | string | - | TypeScript project to add the generator to. We recommend creating a ts#project in a top-level 'tools' directory. |
name 必需 | string | - | Generator name |
description | string | - | A description of your generator |
directory | string | - | The directory within the plugin project's source folder to add the generator to (default: <name>) |
生成器输出
生成器将在指定的 pluginProject
中创建以下项目文件:
文件夹src/<name>/
- schema.json 生成器输入模式
- schema.d.ts 模式的 TypeScript 类型定义
- generator.ts 生成器实现存根
- generator.spec.ts 生成器测试
- generators.json Nx 生成器配置
- package.json 创建或更新以添加 “generators” 条目
- tsconfig.json 更新为使用 CommonJS
本生成器会将选定的 pluginProject
更新为使用 CommonJS,因为目前 Nx 生成器仅支持 CommonJS(ESM 支持参考此 GitHub 问题)。
本地生成器
运行 ts#nx-generator
时选择本地 nx-plugin
项目,并指定名称、可选目录和描述。
定义模式
schema.json
文件定义生成器接受的选项,遵循 JSON Schema 格式和 Nx 扩展。
基本结构
schema.json 文件基本结构:
{ "$schema": "https://json-schema.org/schema", "$id": "YourGeneratorName", "title": "生成器标题", "description": "生成器功能描述", "type": "object", "properties": { // 生成器选项 }, "required": ["必填选项1", "必填选项2"]}
简单示例
基础选项示例:
{ "$schema": "https://json-schema.org/schema", "$id": "ComponentGenerator", "title": "创建组件", "description": "创建新 React 组件", "type": "object", "properties": { "name": { "type": "string", "description": "组件名称", "x-priority": "important" }, "directory": { "type": "string", "description": "组件创建目录", "default": "src/components" }, "withTests": { "type": "boolean", "description": "是否生成测试文件", "default": true } }, "required": ["name"]}
交互式提示 (CLI)
通过添加 x-prompt
属性自定义 CLI 提示:
"name": { "type": "string", "description": "组件名称", "x-prompt": "请输入组件名称:"}
布尔选项使用是/否提示:
"withTests": { "type": "boolean", "description": "是否生成测试文件", "x-prompt": "是否生成测试文件?"}
下拉选择
固定选项使用 enum
:
"style": { "type": "string", "description": "使用的样式方案", "enum": ["css", "scss", "styled-components", "none"], "default": "css"}
项目选择下拉
从工作区项目中选择:
"project": { "type": "string", "description": "添加组件的目标项目", "x-prompt": "请选择目标项目:", "x-dropdown": "projects"}
x-dropdown: "projects"
属性使 Nx 填充工作区所有项目。
位置参数
配置命令行位置参数:
"name": { "type": "string", "description": "组件名称", "x-priority": "important", "$default": { "$source": "argv", "index": 0 }}
允许通过 nx g your-generator my-component
而非 nx g your-generator --name=my-component
运行。
设置优先级
使用 x-priority
标记重要选项:
"name": { "type": "string", "description": "组件名称", "x-priority": "important"}
优先级可为 "important"
或 "internal"
,帮助 Nx 在 VSCode 插件和 CLI 中排序。
默认值
为选项提供默认值:
"directory": { "type": "string", "description": "组件创建目录", "default": "src/components"}
更多信息
详细模式说明参考 Nx 生成器选项文档。
使用 schema.d.ts 的 TypeScript 类型
生成器同时创建 schema.d.ts
提供类型定义:
export interface YourGeneratorSchema { name: string; directory?: string; withTests?: boolean;}
该接口用于生成器实现以提供类型安全:
import { YourGeneratorSchema } from './schema';
export default async function (tree: Tree, options: YourGeneratorSchema) { const { name, directory = 'src/components', withTests = true } = options; // ...}
实现生成器
创建生成器后,可在 generator.ts
中编写实现。
生成器函数操作虚拟文件系统 (Tree
),仅在执行完成后写入磁盘(“dry-run” 模式除外)。
常见操作示例:
读写文件
// 读取文件const content = tree.read('path/to/file.ts', 'utf-8');
// 写入文件tree.write('path/to/new-file.ts', 'export const hello = "world";');
// 检查文件存在if (tree.exists('path/to/file.ts')) { // 操作}
模板生成文件
使用 @nx/devkit
的 generateFiles
工具,通过 EJS 模板生成文件:
import { generateFiles, joinPathFragments } from '@nx/devkit';
generateFiles( tree, joinPathFragments(__dirname, 'files'), // 模板目录 'path/to/output', // 输出目录 { name: options.name, nameCamelCase: camelCase(options.name), nameKebabCase: kebabCase(options.name), },);
TypeScript AST 操作
使用 Nx Plugin for AWS 的 tsAstReplace
方法修改 AST:
import { tsAstReplace } from '@aws/nx-plugin/sdk/utils/ast';import * as ts from 'typescript';
// 示例:递增版本号tsAstReplace( tree, 'path/to/version.ts', 'VariableDeclaration:has(Identifier[name="VERSION"]) NumericLiteral', (node: ts.NumericLiteral) => ts.factory.createNumericLiteral(Number(node.text) + 1));
添加依赖
import { addDependenciesToPackageJson } from '@nx/devkit';
addDependenciesToPackageJson( tree, { 'new-dependency': '^1.0.0' }, { 'new-dev-dependency': '^2.0.0' },);
格式化文件
import { formatFilesInSubtree } from '@aws/nx-plugin/sdk/utils/format';
await formatFilesInSubtree(tree, 'optional/path/to/format');
读写 JSON 文件
import { readJson, updateJson } from '@nx/devkit';
// 读取 JSONconst packageJson = readJson(tree, 'package.json');
// 更新 JSONupdateJson(tree, 'tsconfig.json', (json) => { json.compilerOptions.strict = true; return json;});
扩展 Nx Plugin for AWS 生成器
可导入并扩展生成器:
import { tsProjectGenerator } from '@aws/nx-plugin/sdk/ts';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { const callback = await tsProjectGenerator(tree, { ... }); // 扩展逻辑 return callback;};
OpenAPI 生成器
可扩展 TypeScript 客户端生成器:
import { openApiTsClientGenerator } from '@aws/nx-plugin/sdk/open-api';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { await openApiTsClientGenerator(tree, { ... }); // 添加文件};
构建 OpenAPI 操作数据结构:
import { buildOpenApiCodeGenerationData } from '@aws/nx-plugin/sdk/open-api.js';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { const data = await buildOpenApiCodeGenerationData(tree, 'path/to/spec.json'); generateFiles(tree, __dirname, 'output', data);};
模板示例:
export const myOperationNames = [<%_ allOperations.forEach((op) => { _%> '<%- op.name %>',<%_ }); _%>];
参考 GitHub 代码库 获取复杂模板示例。
运行生成器
两种运行方式:
- 安装 Nx Console VSCode Plugin 如果您尚未安装
- 在VSCode中打开Nx控制台
- 点击
Generate (UI)
在"Common Nx Commands"部分 - 搜索
@my-project/nx-plugin - my-generator
- 填写必需参数
- 点击
Generate
pnpm nx g @my-project/nx-plugin:my-generator
yarn nx g @my-project/nx-plugin:my-generator
npx nx g @my-project/nx-plugin:my-generator
bunx nx g @my-project/nx-plugin:my-generator
您还可以执行试运行以查看哪些文件会被更改
pnpm nx g @my-project/nx-plugin:my-generator --dry-run
yarn nx g @my-project/nx-plugin:my-generator --dry-run
npx nx g @my-project/nx-plugin:my-generator --dry-run
bunx nx g @my-project/nx-plugin:my-generator --dry-run
测试生成器
单元测试示例:
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';import { yourGenerator } from './generator';
describe('your generator', () => { let tree;
beforeEach(() => { tree = createTreeWithEmptyWorkspace(); tree.write('project.json', JSON.stringify({ name: 'test-project' })); });
it('生成预期文件', async () => { await yourGenerator(tree, { name: 'test' }); expect(tree.exists('src/test/file.ts')).toBeTruthy(); expect(tree.read('src/test/file.ts')).toMatchSnapshot(); });
it('更新现有文件', async () => { await yourGenerator(tree, { name: 'test' }); expect(tree.read('src/existing-file.ts')).toContain('import { test }'); });
it('错误处理', async () => { await expect(yourGenerator(tree, { name: 'invalid' })) .rejects.toThrow('预期错误信息'); });});
测试要点:
- 使用
createTreeWithEmptyWorkspace()
创建虚拟文件系统 - 设置前置文件
- 测试文件创建与更新
- 使用快照测试复杂内容
- 测试错误条件
向 @aws/nx-plugin 贡献生成器
在仓库内使用 ts#nx-generator
生成以下文件:
文件夹packages/nx-plugin/src/<name>/
- schema.json
- schema.d.ts
- generator.ts
- generator.spec.ts
文件夹docs/src/content/docs/guides/
- <name>.mdx
- packages/nx-plugin/generators.json 更新包含生成器