Skip to content

ジェネレーターを作成する

@aws/nx-plugin に新しいジェネレータを作成して貢献しましょう。今回の目的はtRPC API向けの新しいプロシージャを生成する機能を追加することです。

まずプラグインをクローンします:

Terminal window
git clone git@github.com:awslabs/nx-plugin-for-aws.git

次にインストールとビルド:

Terminal window
cd nx-plugin-for-aws
pnpm i
pnpm nx run-many --target build --all

新しいジェネレータを packages/nx-plugin/src/trpc/procedure に作成します。

新しいジェネレータを素早く作成するためのジェネレータを用意しています!以下のコマンドで実行できます:

  1. インストール Nx Console VSCode Plugin まだインストールしていない場合
  2. VSCodeでNxコンソールを開く
  3. クリック Generate (UI) "Common Nx Commands"セクションで
  4. 検索 @aws/nx-plugin - ts#nx-generator
  5. 必須パラメータを入力
    • pluginProject: @aws/nx-plugin
    • name: ts#trpc-api#procedure
    • directory: trpc/procedure
    • description: Adds a procedure to a tRPC API
  6. クリック Generate

以下のファイルが自動生成されます:

  • Directorypackages/nx-plugin/src/trpc/procedure
    • schema.json ジェネレータの入力定義
    • schema.d.ts スキーマに対応するTypeScriptインターフェース
    • generator.ts Nxが実行するジェネレータ関数
    • generator.spec.ts ジェネレータのテスト
  • Directorydocs/src/content/docs/guides/
    • trpc-procedure.mdx ジェネレータのドキュメンテーション
  • packages/nx-plugin/generators.json ジェネレータ定義の更新

ジェネレータに必要なプロパティをスキーマに追加します:

{
"$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プロジェクト",
"x-prompt": "プロシージャを追加するtRPC APIプロジェクトを選択",
"x-dropdown": "projects",
"x-priority": "important"
},
"procedure": {
"description": "新規プロシージャ名",
"type": "string",
"x-prompt": "新規プロシージャの名前を入力",
"x-priority": "important",
},
"type": {
"description": "生成するプロシージャのタイプ",
"type": "string",
"x-prompt": "プロシージャのタイプを選択",
"x-priority": "important",
"default": "query",
"enum": ["query", "mutation"]
}
},
"required": ["project", "procedure"]
}

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にプロシージャを追加するには2つの作業が必要です:

  1. 新しいプロシージャ用TypeScriptファイルの作成
  2. ルーターへのプロシージャ追加

generateFiles ユーティリティを使用してEJSテンプレートをレンダリングします。テンプレートはユーザーが選択したオプションに基づいて変数を展開します。

テンプレートファイル packages/nx-plugin/src/trpc/procedure/files/procedures/__procedureNameKebabCase__.ts.template を作成:

files/procedures/__procedureNameKebabCase__.ts.template
import { publicProcedure } from '../init.js';
import { z } from 'zod/v4';
export const <%- procedureNameCamelCase %> = publicProcedure
.input(z.object({
// TODO: 入力定義
}))
.output(z.object({
// TODO: 出力定義
}))
.<%- procedureType %>(async ({ input, ctx }) => {
// TODO: 実装
return {};
});

テンプレートで参照している3つの変数:

  • procedureNameCamelCase
  • procedureNameKebabCase
  • procedureType

これらを generateFiles に渡す必要があります。ユーザーが選択したプロジェクトのソースルート(sourceRoot)をプロジェクト設定から取得します。

ジェネレータを更新:

procedure/generator.ts
import {
generateFiles,
joinPathFragments,
readProjectConfiguration,
Tree,
} from '@nx/devkit';
import { TrpcProcedureSchema } from './schema';
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(__dirname, 'files'),
projectConfig.sourceRoot,
{
procedureNameCamelCase,
procedureNameKebabCase,
procedureType: options.type,
},
);
await formatFilesInSubtree(tree);
};
export default trpcProcedureGenerator;

ルーターへのプロシージャ追加

Section titled “ルーターへのプロシージャ追加”

TypeScript AST操作でソースファイルを更新します。replacedestructuredImport ヘルパーを使用します。

procedure/generator.ts
import {
generateFiles,
joinPathFragments,
readProjectConfiguration,
Tree,
} from '@nx/devkit';
import { TrpcProcedureSchema } from './schema';
import { formatFilesInSubtree } from '../../utils/format';
import camelCase from 'lodash.camelcase';
import kebabCase from 'lodash.kebabcase';
import { destructuredImport, replace } from '../../utils/ast';
import { factory, ObjectLiteralExpression } from 'typescript';
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(__dirname, 'files'),
projectConfig.sourceRoot,
{
procedureNameCamelCase,
procedureNameKebabCase,
procedureType: options.type,
},
);
const routerPath = joinPathFragments(projectConfig.sourceRoot, 'router.ts');
destructuredImport(
tree,
routerPath,
[procedureNameCamelCase],
`./procedures/${procedureNameKebabCase}.js`,
);
replace(
tree,
routerPath,
'CallExpression[expression.name="router"] > ObjectLiteralExpression',
(node) =>
factory.createObjectLiteralExpression([
...(node as ObjectLiteralExpression).properties,
factory.createShorthandPropertyAssignment(procedureNameCamelCase),
]),
);
await formatFilesInSubtree(tree);
};
export default trpcProcedureGenerator;

ジェネレータをコンパイル:

Terminal window
pnpm nx run @aws/nx-plugin:compile

ローカルのNx Plugin for AWSを既存コードベースにリンクしてテストします。

tRPC APIを含むテストプロジェクト作成

Section titled “tRPC APIを含むテストプロジェクト作成”

別ディレクトリで新規ワークスペースを作成:

Terminal window
npx create-nx-workspace@~21.0.3 trpc-generator-test --pm=pnpm --preset=@aws/nx-plugin --ci=skip

tRPC APIを生成:

  1. インストール Nx Console VSCode Plugin まだインストールしていない場合
  2. VSCodeでNxコンソールを開く
  3. クリック Generate (UI) "Common Nx Commands"セクションで
  4. 検索 @aws/nx-plugin - ts#trpc-api
  5. 必須パラメータを入力
    • apiName: test-api
  6. クリック Generate

@aws/nx-plugin をリンク:

Terminal window
cd path/to/trpc-generator-test
pnpm link path/to/nx-plugin-for-aws/dist/packages/nx-plugin

新規ジェネレータを実行:

  1. インストール Nx Console VSCode Plugin まだインストールしていない場合
  2. VSCodeでNxコンソールを開く
  3. クリック Generate (UI) "Common Nx Commands"セクションで
  4. 検索 @aws/nx-plugin - ts#trpc-api#procedure
  5. 必須パラメータを入力
    • クリック Generate

    成功すると、新しいプロシージャが生成され router.ts に追加されます。

    さらに時間がある方は、ジェネレータに以下の機能を追加してみてください:

    ドット表記の procedure 入力(例:games.query)をサポート:

    • 逆ドット表記のプロシージャ名生成(例:queryGames
    • 適切なネスト化ルーターの追加/更新

    tRPC APIでないプロジェクトが選択された場合の防御処理を追加。api-connection ジェネレータを参考にしてください。

    ジェネレータのユニットテスト実装:

    1. createTreeUsingTsSolutionSetup() で空ワークスペース作成
    2. 既存ファイル(project.jsonsrc/router.ts)をツリーに追加
    3. ジェネレータ実行
    4. 期待通りの変更を検証

    現在の「smoke test」を更新して新規ジェネレータを含める。すべてのジェネレータのビルド成功を確認します。