Nxジェネレータージェネレーター
Nx GeneratorをTypeScriptプロジェクトに追加し、コンポーネントのスキャフォールディングや特定のプロジェクト構造の強制など、反復的なタスクの自動化を支援します。
使用方法
ジェネレーターの生成
ジェネレーターは2つの方法で生成できます:
- インストール 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
内に以下のプロジェクトファイルを作成します:
Directorysrc/<name>/
- schema.json ジェネレーターの入力スキーマ
- schema.d.ts スキーマのTypeScript型定義
- generator.ts ジェネレーター実装のスタブ
- generator.spec.ts ジェネレーターのテスト
- generators.json ジェネレーター定義用Nx設定
- package.json 「generators」エントリを追加/更新
- tsconfig.json CommonJS使用に更新
現在NxジェネレーターはCommonJSのみをサポートしているため、このジェネレーターは選択されたpluginProject
をCommonJS使用に更新します(ESMサポートに関するGitHub Issue)。
ローカルジェネレーター
ts#nx-generator
ジェネレーター実行時にローカルのnx-plugin
プロジェクトを選択し、名前とオプションのディレクトリ、説明を指定してください。
スキーマの定義
schema.json
ファイルはジェネレーターが受け入れるオプションを定義します。JSON Schema形式にNx拡張を加えた形式です。
基本構造
schema.jsonファイルの基本構造:
{ "$schema": "https://json-schema.org/schema", "$id": "YourGeneratorName", "title": "Your Generator Title", "description": "Description of what your generator does", "type": "object", "properties": { // ジェネレーターオプションをここに記述 }, "required": ["requiredOption1", "requiredOption2"]}
シンプルな例
基本的なオプションを含むシンプルな例:
{ "$schema": "https://json-schema.org/schema", "$id": "ComponentGenerator", "title": "Create a Component", "description": "Creates a new React component", "type": "object", "properties": { "name": { "type": "string", "description": "Component name", "x-priority": "important" }, "directory": { "type": "string", "description": "Directory where the component will be created", "default": "src/components" }, "withTests": { "type": "boolean", "description": "Whether to generate test files", "default": true } }, "required": ["name"]}
インタラクティブプロンプト(CLI)
x-prompt
プロパティを追加してCLI実行時のプロンプトをカスタマイズ:
"name": { "type": "string", "description": "Component name", "x-prompt": "What is the name of your component?"}
真偽値オプションではyes/noプロンプトを使用:
"withTests": { "type": "boolean", "description": "Whether to generate test files", "x-prompt": "Would you like to generate test files?"}
ドロップダウン選択肢
固定選択肢があるオプションにはenum
を使用:
"style": { "type": "string", "description": "The styling approach to use", "enum": ["css", "scss", "styled-components", "none"], "default": "css"}
プロジェクト選択ドロップダウン
ワークスペース内の既存プロジェクトから選択させる一般的なパターン:
"project": { "type": "string", "description": "The project to add the component to", "x-prompt": "Which project would you like to add the component to?", "x-dropdown": "projects"}
x-dropdown: "projects"
プロパティはNxにワークスペース内の全プロジェクトをドロップダウンに表示するよう指示します。
位置引数
コマンドラインから位置引数としてオプションを渡す設定:
"name": { "type": "string", "description": "Component name", "x-priority": "important", "$default": { "$source": "argv", "index": 0 }}
これによりnx g your-generator my-component
のように名前を引数で渡せるようになります。
優先度の設定
x-priority
プロパティで重要度を表示:
"name": { "type": "string", "description": "Component name", "x-priority": "important"}
優先度は"important"
または"internal"
を指定可能。Nx VSCode拡張やCLIでのプロパティ順序付けに役立ちます。
デフォルト値
オプションにデフォルト値を設定:
"directory": { "type": "string", "description": "Directory where the component will be created", "default": "src/components"}
詳細情報
スキーマの詳細についてはNx Generator Optionsドキュメントを参照。
schema.d.tsによるTypeScript型
schema.json
と共に生成されるschema.d.ts
ファイルはジェネレーターオプションのTypeScript型を提供します:
export interface YourGeneratorSchema { name: string; directory?: string; withTests?: boolean;}
このインターフェースはジェネレーター実装で型安全性とコード補完に使用されます:
import { YourGeneratorSchema } from './schema';
export default async function (tree: Tree, options: YourGeneratorSchema) { // オプションの型がTypeScriptで認識される 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')) { // 処理を実行}
テンプレートからのファイル生成
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操作
TSQueryの使用を推奨します。
import { tsquery } from '@phenomnomnominal/tsquery';import * as ts from 'typescript';
// 例: ファイル内バージョン番号のインクリメント
// ファイル内容をTypeScript ASTにパースconst sourceFile = tsquery.ast(tree.read('path/to/version.ts', 'utf-8'));
// セレクターに一致するノードを検索const nodes = tsquery.query( sourceFile, 'VariableDeclaration:has(Identifier[name="VERSION"]) NumericLiteral',);
if (nodes.length > 0) { // 数値リテラルノードを取得 const numericNode = nodes[0] as ts.NumericLiteral;
// 現在のバージョンを取得してインクリメント const currentVersion = Number(numericNode.text); const newVersion = currentVersion + 1;
// ASTノードを置換 const result = tsquery.replace( sourceFile, 'VariableDeclaration:has(Identifier[name="VERSION"]) NumericLiteral', () => ts.factory.createNumericLiteral(newVersion), );
// 更新内容をtreeに書き込み tree.write( 'path/to/version.ts', ts .createPrinter({ newLine: ts.NewLineKind.LineFeed, }) .printNode(ts.EmitHint.Unspecified, result, sourceFile), );}
依存関係の追加
import { addDependenciesToPackageJson } from '@nx/devkit';
// package.jsonに依存関係を追加addDependenciesToPackageJson( tree, { 'new-dependency': '^1.0.0', }, { 'new-dev-dependency': '^2.0.0', },);
生成ファイルのフォーマット
import { formatFiles } from '@nx/devkit';
// 変更された全ファイルをフォーマットawait formatFiles(tree);
JSONファイルの読み書き
import { readJson, updateJson } from '@nx/devkit';
// JSONファイル読み取りconst packageJson = readJson(tree, 'package.json');
// JSONファイル更新updateJson(tree, 'tsconfig.json', (json) => { json.compilerOptions = { ...json.compilerOptions, strict: true, }; return json;});
ジェネレーターの実行
ジェネレーターは2つの方法で実行できます:
- インストール 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を作成 tree = createTreeWithEmptyWorkspace();
// treeに既存ファイルを追加 tree.write( 'project.json', JSON.stringify({ name: 'test-project', sourceRoot: 'src', }), );
tree.write('src/existing-file.ts', 'export const existing = true;'); });
it('should generate expected files', async () => { // ジェネレーター実行 await yourGenerator(tree, { name: 'test', // その他必須オプション });
// ファイル生成確認 expect(tree.exists('src/test/file.ts')).toBeTruthy();
// ファイル内容確認 const content = tree.read('src/test/file.ts', 'utf-8'); expect(content).toContain('export const test');
// スナップショットも使用可能 expect(tree.read('src/test/file.ts', 'utf-8')).toMatchSnapshot(); });
it('should update existing files', async () => { // ジェネレーター実行 await yourGenerator(tree, { name: 'test', // その他必須オプション });
// 既存ファイルの更新確認 const content = tree.read('src/existing-file.ts', 'utf-8'); expect(content).toContain('import { test } from'); });
it('should handle errors', async () => { // 特定条件でのエラー発生を確認 await expect( yourGenerator(tree, { name: 'invalid', // エラーを引き起こすオプション }), ).rejects.toThrow('Expected error message'); });});
テストの要点:
createTreeWithEmptyWorkspace()
で仮想ファイルシステムを作成- ジェネレーター実行前の前提条件ファイルを設定
- 新規ファイル生成と既存ファイル更新の両方をテスト
- 複雑なファイル内容にはスナップショットを使用
- エラー発生条件をテストして適切な失敗を確認
@aws/nx-pluginへのジェネレーターの提供
ts#nx-generator
を使用して@aws/nx-plugin
内にジェネレーターのスキャフォールドを作成できます。
このジェネレーターをリポジトリ内で実行すると、以下のファイルが生成されます:
Directorypackages/nx-plugin/src/<name>/
- schema.json ジェネレーター入力スキーマ
- schema.d.ts スキーマのTypeScript型定義
- generator.ts ジェネレーター実装
- generator.spec.ts テスト
Directorydocs/src/content/docs/guides/
- <name>.mdx ジェネレーターのドキュメントページ
- packages/nx-plugin/generators.json ジェネレーター定義を更新
その後、ジェネレーターの実装を開始できます。