贡献生成器
让我们创建一个新的生成器来贡献给 @aws/nx-plugin。我们的目标是为 tRPC API 生成一个新的过程。
首先,让我们克隆插件:
git clone git@github.com:awslabs/nx-plugin-for-aws.git接下来,安装并构建:
cd nx-plugin-for-awspnpm ipnpm nx run-many --target build --all创建一个空生成器
Section titled “创建一个空生成器”让我们在 packages/nx-plugin/src/trpc/procedure 中创建新的生成器。
我们提供了一个用于创建新生成器的生成器,这样您就可以快速搭建新生成器的脚手架!您可以按如下方式运行此生成器:
pnpm nx g @aws/nx-plugin:ts#nx-generator --project=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC APIyarn nx g @aws/nx-plugin:ts#nx-generator --project=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC APInpx nx g @aws/nx-plugin:ts#nx-generator --project=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC APIbunx nx g @aws/nx-plugin:ts#nx-generator --project=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API您还可以执行试运行以查看哪些文件会被更改
pnpm nx g @aws/nx-plugin:ts#nx-generator --project=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-runyarn nx g @aws/nx-plugin:ts#nx-generator --project=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-runnpx nx g @aws/nx-plugin:ts#nx-generator --project=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-runbunx nx g @aws/nx-plugin:ts#nx-generator --project=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-run- 安装 Nx Console VSCode Plugin 如果您尚未安装
- 在VSCode中打开Nx控制台
- 点击
Generate (UI)在"Common Nx Commands"部分 - 搜索
@aws/nx-plugin - ts#nx-generator - 填写必需参数
- project: @aws/nx-plugin
- name: ts#trpc-api#procedure
- directory: trpc/procedure
- description: Adds a procedure to a tRPC API
- 点击
Generate
您会注意到已为您生成了以下文件:
文件夹packages/nx-plugin/src/trpc/procedure
- schema.json 定义生成器的输入
- schema.d.ts 与 schema 匹配的 TypeScript 接口
- generator.ts Nx 作为生成器运行的函数
- generator.spec.ts 生成器的测试
文件夹docs/src/content/docs/guides/
- trpc-procedure.mdx 生成器的文档
- packages/nx-plugin/generators.json 已更新以包含生成器
让我们更新 schema 以添加生成器所需的属性:
{ "$schema": "https://json-schema.org/schema", "$id": "tRPCProcedure", "title": "Adds a procedure to a tRPC API", "type": "object", "properties": { "project": { "type": "string", "description": "tRPC API project", "x-prompt": "Select the tRPC API project to add the procedure to", "x-dropdown": "projects", "x-priority": "important" }, "procedure": { "description": "The name of the new procedure", "type": "string", "x-prompt": "What would you like to call your new procedure?", "x-priority": "important" }, "type": { "description": "The type of procedure to generate", "type": "string", "x-prompt": "What type of procedure would you like to generate?", "x-priority": "important", "default": "query", "enum": ["query", "mutation"] } }, "required": ["project", "procedure"]}export interface TrpcProcedureSchema { project: string; procedure: string; type: 'query' | 'mutation';}您会注意到生成器已经在 packages/nx-plugin/generators.json 中连接好了:
... "generators": { ... "ts#trpc-api#procedure": { "factory": "./src/trpc/procedure/generator", "schema": "./src/trpc/procedure/schema.json", "description": "Adds a procedure to a tRPC API" } },...要向 tRPC API 添加过程,我们需要做两件事:
- 为新过程创建一个 TypeScript 文件
- 将过程添加到路由器
要为新过程创建 TypeScript 文件,我们将使用一个名为 generateFiles 的实用程序。使用它,我们可以定义一个 EJS 模板,我们可以在生成器中根据用户选择的选项使用变量来渲染它。
首先,我们将在 packages/nx-plugin/src/trpc/procedure/files/procedures/__procedureNameKebabCase__.ts.template 中定义模板:
import { publicProcedure } from '../init.js';import { z } from 'zod';
export const <%- procedureNameCamelCase %> = publicProcedure .input(z.object({ // TODO: define input })) .output(z.object({ // TODO: define output })) .<%- procedureType %>(async ({ input, ctx }) => { // TODO: implement! return {}; });在模板中,我们引用了三个变量:
procedureNameCamelCaseprocedureNameKebabCaseprocedureType
因此,我们需要确保将这些变量传递给 generateFiles,以及生成文件的目录,即用户选择作为生成器输入的 tRPC 项目的源文件位置(即 sourceRoot),我们可以从项目配置中提取它。
让我们更新生成器来做到这一点:
import { generateFiles, joinPathFragments, readProjectConfiguration, type Tree,} from '@nx/devkit';import type { TrpcProcedureSchema } from './schema.js';import { formatFilesInSubtree } from '../../utils/format';import camelCase from 'lodash.camelcase';import kebabCase from 'lodash.kebabcase';
export const trpcProcedureGenerator = async ( tree: Tree, options: TrpcProcedureSchema,) => { const projectConfig = readProjectConfiguration(tree, options.project);
const procedureNameCamelCase = camelCase(options.procedure); const procedureNameKebabCase = kebabCase(options.procedure);
generateFiles( tree, joinPathFragments(import.meta.dirname, 'files'), projectConfig.sourceRoot, { procedureNameCamelCase, procedureNameKebabCase, procedureType: options.type, }, );
await formatFilesInSubtree(tree);};
export default trpcProcedureGenerator;将过程添加到路由器
Section titled “将过程添加到路由器”接下来,我们希望生成器将新过程连接到路由器。这意味着读取和更新用户的源代码!
我们使用 GritQL 以声明方式搜索和转换源代码。addDestructuredImport 辅助函数添加命名导入,applyGritQL 应用 GritQL 模式将过程添加到路由器的对象字面量。
import { generateFiles, joinPathFragments, readProjectConfiguration, type Tree,} from '@nx/devkit';import type { TrpcProcedureSchema } from './schema.js';import { formatFilesInSubtree } from '../../utils/format';import camelCase from 'lodash.camelcase';import kebabCase from 'lodash.kebabcase';import { addDestructuredImport, applyGritQL } from '../../utils/ast';
export const trpcProcedureGenerator = async ( tree: Tree, options: TrpcProcedureSchema,) => { const projectConfig = readProjectConfiguration(tree, options.project);
const procedureNameCamelCase = camelCase(options.procedure); const procedureNameKebabCase = kebabCase(options.procedure);
generateFiles( tree, joinPathFragments(import.meta.dirname, 'files'), projectConfig.sourceRoot, { procedureNameCamelCase, procedureNameKebabCase, procedureType: options.type, }, );
const routerPath = joinPathFragments(projectConfig.sourceRoot, 'router.ts');
await addDestructuredImport( tree, routerPath, [procedureNameCamelCase], `./procedures/${procedureNameKebabCase}.js`, );
await applyGritQL( tree, routerPath, `\`router({ $props })\` => \`router({ $props, ${procedureNameCamelCase} })\` where { $props <: not contains \`${procedureNameCamelCase}\` }`, );
await formatFilesInSubtree(tree);};
export default trpcProcedureGenerator;现在我们已经实现了生成器,让我们编译它以确保它可供我们在地牢冒险项目中测试。
pnpm nx compile @aws/nx-plugin要测试生成器,我们将把本地的 Nx Plugin for AWS 链接到现有代码库。
创建一个带有 tRPC API 的测试项目
Section titled “创建一个带有 tRPC API 的测试项目”在单独的目录中,创建一个新的测试工作区:
pnpm create @aws/nx-workspace trpc-generator-testyarn create @aws/nx-workspace trpc-generator-testnpm create @aws/nx-workspace -- trpc-generator-testbun create @aws/nx-workspace trpc-generator-test接下来,让我们生成一个 tRPC API 来添加过程:
pnpm nx g @aws/nx-plugin:ts#api --name=test-api --framework=trpc --no-interactiveyarn nx g @aws/nx-plugin:ts#api --name=test-api --framework=trpc --no-interactivenpx nx g @aws/nx-plugin:ts#api --name=test-api --framework=trpc --no-interactivebunx nx g @aws/nx-plugin:ts#api --name=test-api --framework=trpc --no-interactive您还可以执行试运行以查看哪些文件会被更改
pnpm nx g @aws/nx-plugin:ts#api --name=test-api --framework=trpc --no-interactive --dry-runyarn nx g @aws/nx-plugin:ts#api --name=test-api --framework=trpc --no-interactive --dry-runnpx nx g @aws/nx-plugin:ts#api --name=test-api --framework=trpc --no-interactive --dry-runbunx nx g @aws/nx-plugin:ts#api --name=test-api --framework=trpc --no-interactive --dry-run- 安装 Nx Console VSCode Plugin 如果您尚未安装
- 在VSCode中打开Nx控制台
- 点击
Generate (UI)在"Common Nx Commands"部分 - 搜索
@aws/nx-plugin - ts#api - 填写必需参数
- name: test-api
- framework: trpc
- 点击
Generate
链接我们的本地 Nx Plugin for AWS
Section titled “链接我们的本地 Nx Plugin for AWS”在您的代码库中,让我们链接本地的 @aws/nx-plugin:
cd path/to/trpc-generator-testpnpm link path/to/nx-plugin-for-aws/dist/packages/nx-plugincd path/to/trpc-generator-testyarn link path/to/nx-plugin-for-aws/dist/packages/nx-plugincd path/to/trpc-generator-testnpm link path/to/nx-plugin-for-aws/dist/packages/nx-plugincd path/to/nx-plugin-for-aws/dist/packages/nx-pluginbun linkcd path/to/trpc-generator-testbun link @aws/nx-plugin运行新生成器
Section titled “运行新生成器”让我们尝试新的生成器:
pnpm nx g @aws/nx-plugin:ts#trpc-api#procedureyarn nx g @aws/nx-plugin:ts#trpc-api#procedurenpx nx g @aws/nx-plugin:ts#trpc-api#procedurebunx nx g @aws/nx-plugin:ts#trpc-api#procedure您还可以执行试运行以查看哪些文件会被更改
pnpm nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-runyarn nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-runnpx nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-runbunx nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-run- 安装 Nx Console VSCode Plugin 如果您尚未安装
- 在VSCode中打开Nx控制台
- 点击
Generate (UI)在"Common Nx Commands"部分 - 搜索
@aws/nx-plugin - ts#trpc-api#procedure - 填写必需参数
- 点击
Generate
如果成功,我们应该已经生成了一个新过程,并在 router.ts 中将过程添加到我们的路由器。
如果您已经走到这一步并且还有一些时间来尝试 Nx 生成器,这里有一些建议可以添加到过程生成器的功能:
1. 嵌套操作
Section titled “1. 嵌套操作”尝试更新生成器以支持嵌套路由器,方法是:
- 接受
procedure输入的点表示法(例如games.query) - 根据反向点表示法生成具有名称的过程(例如
queryGames) - 添加适当的嵌套路由器(或者如果已经存在则更新它!)
我们的生成器应该防范潜在问题,例如用户选择的 project 不是 tRPC API。查看 connection 生成器以获取此示例。
3. 单元测试
Section titled “3. 单元测试”为生成器编写一些单元测试。这些相当简单易实现,大多数遵循一般流程:
- 使用
createTreeUsingTsSolutionSetup()创建一个空的工作区树 - 在树中添加应该已经存在的任何文件(例如 tRPC 后端的
project.json和src/router.ts) - 运行正在测试的生成器
- 验证对树进行了预期的更改
4. 端到端测试
Section titled “4. 端到端测试”我们有一套”冒烟测试”,在新工作区中运行生成器并确保一切都能构建。至少,您的新生成器应该添加到两个生成器矩阵中,以便冒烟测试对其进行测试:
e2e/src/smoke-tests/generator-matrix.ts— 通过 CLI 运行每个生成器,一次一个调用,就像用户一样。packages/nx-plugin/src/internal/test-matrix/generator.ts— 一个隐藏的生成器,它组合所有其他生成器以测试版本之间的迁移。
请注意,生成器矩阵仅运行生成器并构建工作区——它不会实例化任何基础设施。对于部署基础设施的生成器,请考虑扩展部署 e2e 测试(e2e/src/smoke-tests/cdk-deploy.spec.ts 和 terraform-deploy.spec.ts)以实际部署您的资源(通过 cdk deploy / terraform apply),然后向 deploy-invocations.ts 添加一个断言,调用已部署的资源并验证其行为符合预期。
如果您的生成器提供本地开发服务器,请考虑将其添加到本地开发 e2e 测试(e2e/src/smoke-tests/local-dev.spec.ts)中,该测试启动 dev 目标并测试运行中的服务器。
加速贡献的通用指导
Section titled “加速贡献的通用指导”本节包含一些在使用 Nx Plugin for AWS 时有帮助的通用指导。
从真实项目向后工作
Section titled “从真实项目向后工作”构建新生成器或向现有生成器添加功能/修复的一个有用方法是_首先真实地构建它_。这样,您可以验证您的想法并快速迭代以实现所需的功能。在确定所需结果后,您可以更新生成器。
在实践中,此过程可能如下所示:
-
创建一个新工作区
Terminal window pnpm create @aws/nx-workspace my-projectTerminal window yarn create @aws/nx-workspace my-projectTerminal window npm create @aws/nx-workspace -- my-projectTerminal window bun create @aws/nx-workspace my-project -
运行可能是新生成器/功能/修复的先决条件的任何生成器
-
提交您的更改(
git commit) -
进行所需的更改并根据需要进行测试
-
使用更改的
git diff来告知应该对 Nx Plugin for AWS 进行哪些更改 -
执行最后一次端到端测试(链接您的
@aws/nx-plugin)以确保您的生成器提供您需要的更改