Nx Generator Generator
컴포넌트 스캐폴딩이나 특정 프로젝트 구조 적용과 같은 반복적인 작업을 자동화하는 데 도움이 되는 Nx Generator를 TypeScript 프로젝트에 추가합니다.
사용법
섹션 제목: “사용법”Generator 생성하기
섹션 제목: “Generator 생성하기”두 가지 방법으로 generator를 생성할 수 있습니다:
pnpm nx g @aws/nx-plugin:ts#nx-generatoryarn nx g @aws/nx-plugin:ts#nx-generatornpx nx g @aws/nx-plugin:ts#nx-generatorbunx nx g @aws/nx-plugin:ts#nx-generator어떤 파일이 변경될지 확인하기 위해 드라이 런을 수행할 수도 있습니다
pnpm nx g @aws/nx-plugin:ts#nx-generator --dry-runyarn nx g @aws/nx-plugin:ts#nx-generator --dry-runnpx nx g @aws/nx-plugin:ts#nx-generator --dry-runbunx nx g @aws/nx-plugin:ts#nx-generator --dry-run- 설치 Nx Console VSCode Plugin 아직 설치하지 않았다면
- VSCode에서 Nx 콘솔 열기
- 클릭
Generate (UI)"Common Nx Commands" 섹션에서 - 검색
@aws/nx-plugin - ts#nx-generator - 필수 매개변수 입력
- 클릭
Generate
| 매개변수 | 타입 | 기본값 | 설명 |
|---|---|---|---|
| project 필수 | string | - | 생성기를 추가할 TypeScript 프로젝트입니다. ts#nx-plugin 생성기를 사용하여 생성하는 것을 권장합니다. |
| name 필수 | string | - | 생성기 이름 |
| description | string | - | 생성기에 대한 설명 |
| directory | string | - | 생성기를 추가할 플러그인 프로젝트의 소스 폴더 내 디렉토리 (기본값: <name>) |
| preferInstallDependencies | boolean | true | 생성기 실행 후 의존성 설치를 선호할지 여부입니다. 여러 생성기를 일괄 처리할 때 설치를 연기하려면 false로 설정하세요(후속 생성기가 Nx 프로젝트 그래프를 계산할 수 있도록 필요한 경우 설치는 여전히 실행됩니다). 마지막에 한 번만 설치하세요. |
Generator 출력
섹션 제목: “Generator 출력”Generator는 주어진 project 내에 다음 프로젝트 파일들을 생성합니다:
디렉터리src/<name>/
- schema.json Schema for input to your generator
- schema.d.ts TypeScript types for your schema
- generator.ts Stub generator implementation
- generator.spec.ts Tests for your generator
- README.md Documentation for your generator
- generators.json Nx configuration to define your generators
- package.json Created or updated to add a “generators” entry
- tsconfig.json Updated to use CommonJS
프로젝트 수정
이 generator는 선택한 project를 CommonJS를 사용하도록 업데이트합니다. Nx Generator는 현재 CommonJS만 지원하기 때문입니다 (ESM 지원에 대한 GitHub 이슈 참조).
로컬 Generator
섹션 제목: “로컬 Generator”ts#nx-generator generator를 실행할 때 로컬 nx-plugin 프로젝트를 선택하고, 이름과 선택적으로 디렉토리 및 설명을 지정하세요.
스키마 정의하기
섹션 제목: “스키마 정의하기”schema.json 파일은 generator가 받는 옵션을 정의합니다. Nx 전용 확장이 포함된 JSON Schema 형식을 따릅니다.
기본 구조
섹션 제목: “기본 구조”schema.json 파일은 다음과 같은 기본 구조를 가집니다:
{ "$schema": "https://json-schema.org/schema", "$id": "YourGeneratorName", "title": "Your Generator Title", "description": "Description of what your generator does", "type": "object", "properties": { // Your generator options go here }, "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)
섹션 제목: “대화형 프롬프트 (CLI)”x-prompt 속성을 추가하여 CLI를 통해 generator를 실행할 때 표시되는 프롬프트를 사용자 정의할 수 있습니다:
"name": { "type": "string", "description": "Component name", "x-prompt": "What is the name of your component?"}boolean 옵션의 경우 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에게 워크스페이스의 모든 프로젝트로 드롭다운을 채우도록 지시합니다.
위치 인수
섹션 제목: “위치 인수”generator를 명령줄에서 실행할 때 위치 인수로 전달되도록 옵션을 구성할 수 있습니다:
"name": { "type": "string", "description": "Component name", "x-priority": "important", "$default": { "$source": "argv", "index": 0 }}이렇게 하면 사용자가 nx g your-generator --name=my-component 대신 nx g your-generator my-component와 같이 generator를 실행할 수 있습니다.
우선순위 설정
섹션 제목: “우선순위 설정”x-priority 속성을 사용하여 가장 중요한 옵션을 표시합니다:
"name": { "type": "string", "description": "Component name", "x-priority": "important"}옵션은 "important" 또는 "internal" 우선순위를 가질 수 있습니다. 이는 Nx VSCode 확장 및 Nx CLI에서 속성을 정렬하는 데 도움이 됩니다.
기본값
섹션 제목: “기본값”옵션에 기본값을 제공할 수 있습니다:
"directory": { "type": "string", "description": "Directory where the component will be created", "default": "src/components"}추가 정보
섹션 제목: “추가 정보”스키마에 대한 자세한 내용은 Nx Generator Options 문서를 참조하세요.
schema.d.ts를 사용한 TypeScript 타입
섹션 제목: “schema.d.ts를 사용한 TypeScript 타입”schema.json과 함께 generator는 generator 옵션에 대한 TypeScript 타입을 제공하는 schema.d.ts 파일을 생성합니다:
export interface YourGeneratorSchema { name: string; directory?: string; withTests?: boolean;}이 인터페이스는 타입 안전성과 코드 완성을 제공하기 위해 generator 구현에서 사용됩니다:
import { YourGeneratorSchema } from './schema';
export default async function (tree: Tree, options: YourGeneratorSchema) { // TypeScript knows the types of all your options const { name, directory = 'src/components', withTests = true } = options; // ...}Generator 구현하기
섹션 제목: “Generator 구현하기”위와 같이 새 generator를 생성한 후 generator.ts에 구현을 작성할 수 있습니다.
Generator는 가상 파일 시스템(Tree)을 변경하여 파일을 읽고 쓰면서 원하는 변경 사항을 적용하는 함수입니다. Tree의 변경 사항은 generator가 실행을 완료한 후에만 디스크에 기록되며, “dry-run” 모드로 실행되지 않는 한 그렇습니다. 빈 generator는 다음과 같습니다:
export const myGenerator = async (tree: Tree, options: MyGeneratorSchema) => { // Use the tree to apply changes};
export default myGenerator;다음은 generator에서 수행할 수 있는 몇 가지 일반적인 작업입니다:
파일 읽기 및 쓰기
섹션 제목: “파일 읽기 및 쓰기”// Read a fileconst content = tree.read('path/to/file.ts', 'utf-8');
// Write a filetree.write('path/to/new-file.ts', 'export const hello = "world";');
// Check if a file existsif (tree.exists('path/to/file.ts')) { // Do something}템플릿에서 파일 생성하기
섹션 제목: “템플릿에서 파일 생성하기”@nx/devkit의 generateFiles 유틸리티를 사용하여 파일을 생성할 수 있습니다. 이를 통해 EJS 구문으로 템플릿을 정의하고 변수를 대체할 수 있습니다.
import { generateFiles, joinPathFragments } from '@nx/devkit';
// Generate files from templatesgenerateFiles( tree, joinPathFragments(import.meta.dirname, 'files'), // Template directory 'path/to/output', // Output directory { // Variables to replace in templates name: options.name, nameCamelCase: camelCase(options.name), nameKebabCase: kebabCase(options.name), // Add more variables as needed },);GritQL을 사용한 코드 변환
섹션 제목: “GritQL을 사용한 코드 변환”GritQL을 사용하여 generator에서 소스 코드를 선언적으로 검색하고 변환할 수 있습니다. GritQL은 TypeScript, JavaScript, Python, HCL (Terraform) 등 여러 언어를 지원하므로 전체 스택에서 동일한 패턴 구문을 사용할 수 있습니다.
Nx Plugin for AWS는 두 가지 헬퍼를 제공합니다:
applyGritQL(tree, filePath, pattern)— 파일에 GritQL 재작성 패턴을 적용하고 변경 사항이 있었는지 나타내는Promise<boolean>을 반환합니다matchGritQL(tree, filePath, pattern)— GritQL 패턴이 파일의 어딘가에 일치하는지 확인하고Promise<boolean>을 반환합니다
import { applyGritQL, matchGritQL } from '@aws/nx-plugin/sdk/utils/ast';
// Replace a function callawait applyGritQL( tree, 'src/app.ts', '`console.log($msg)` => `logger.info($msg)`',);
// Add an element to an array only if not already presentawait applyGritQL( tree, 'src/plugins.ts', '`plugins: [$items]` => `plugins: [$items, myPlugin()]` where { $items <: not contains `myPlugin` }',);
// Check if a pattern exists before making changesif (!(await matchGritQL(tree, filePath, '`import { Auth } from "./auth"`'))) { // Add the import}GritQL 패턴은 TypeScript가 아닌 파일에서도 작동합니다. 다른 언어를 대상으로 하려면 패턴 앞에 language <name>을 붙이세요:
// Python: replace print statements with logging callsawait applyGritQL( tree, 'src/handler.py', 'language python\n`print($msg)` => `logger.info($msg)`',);GritQL 패턴은 와일드카드로 $metavariables를 사용하는 백틱으로 구분된 코드 스니펫을 사용합니다. 재작성에는 =>를, 조건에는 where 절을 사용합니다.
의존성 추가하기
섹션 제목: “의존성 추가하기”import { addDependenciesToPackageJson } from '@nx/devkit';
// Add dependencies to package.jsonaddDependenciesToPackageJson( tree, { 'new-dependency': '^1.0.0', }, { 'new-dev-dependency': '^2.0.0', },);생성된 파일 포맷팅
섹션 제목: “생성된 파일 포맷팅”import { formatFilesInSubtree } from '@aws/nx-plugin/sdk/utils/format';
// Format all files that were modifiedawait formatFilesInSubtree(tree, 'optional/path/to/format');JSON 파일 읽기 및 업데이트
섹션 제목: “JSON 파일 읽기 및 업데이트”import { readJson, updateJson } from '@nx/devkit';
// Read a JSON fileconst packageJson = readJson(tree, 'package.json');
// Update a JSON fileupdateJson(tree, 'tsconfig.json', (json) => { json.compilerOptions = { ...json.compilerOptions, strict: true, }; return json;});Nx Plugin for AWS의 Generator 확장하기
섹션 제목: “Nx Plugin for AWS의 Generator 확장하기”Nx Plugin for AWS에서 generator를 가져와서 원하는 대로 확장하거나 구성할 수 있습니다. 예를 들어 TypeScript 프로젝트를 기반으로 하는 generator를 만들 수 있습니다:
import { tsProjectGenerator } from '@aws/nx-plugin/sdk/ts';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { const callback = await tsProjectGenerator(tree, { ... });
// Extend the TypeScript project generator here
// Return the callback to ensure dependencies are installed. // You can wrap the callback if you wish to perform additional operations in the generator callback. return callback;};OpenAPI Generator
섹션 제목: “OpenAPI Generator”위와 유사한 방식으로 TypeScript 클라이언트 및 훅에 사용하는 generator를 사용하고 확장할 수 있습니다:
import { openApiTsClientGenerator } from '@aws/nx-plugin/sdk/open-api';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { await openApiTsClientGenerator(tree, { ... });
// Add additional files here};또한 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, joinPathFragments(import.meta.dirname, 'files'), // Template directory 'path/to/output', // Output directory data, );};그러면 다음과 같은 템플릿을 작성할 수 있습니다:
export const myOperationNames = [<%_ allOperations.forEach((op) => { _%> '<%- op.name %>',<%_ }); _%>];더 복잡한 예제 템플릿은 GitHub의 코드베이스를 참조하세요.
Generator 실행하기
섹션 제목: “Generator 실행하기”두 가지 방법으로 generator를 실행할 수 있습니다:
pnpm nx g @my-project/nx-plugin:my-generatoryarn nx g @my-project/nx-plugin:my-generatornpx nx g @my-project/nx-plugin:my-generatorbunx nx g @my-project/nx-plugin:my-generator어떤 파일이 변경될지 확인하기 위해 드라이 런을 수행할 수도 있습니다
pnpm nx g @my-project/nx-plugin:my-generator --dry-runyarn nx g @my-project/nx-plugin:my-generator --dry-runnpx nx g @my-project/nx-plugin:my-generator --dry-runbunx nx g @my-project/nx-plugin:my-generator --dry-run- 설치 Nx Console VSCode Plugin 아직 설치하지 않았다면
- VSCode에서 Nx 콘솔 열기
- 클릭
Generate (UI)"Common Nx Commands" 섹션에서 - 검색
@my-project/nx-plugin - my-generator - 필수 매개변수 입력
- 클릭
Generate
Generator 테스트하기
섹션 제목: “Generator 테스트하기”Generator에 대한 단위 테스트는 구현하기 간단합니다. 다음은 일반적인 패턴입니다:
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';import { yourGenerator } from './generator.js';
describe('your generator', () => { let tree;
beforeEach(() => { // Create an empty workspace tree tree = createTreeWithEmptyWorkspace();
// Add any files that should already exist in the 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 () => { // Run the generator await yourGenerator(tree, { name: 'test', // Add other required options });
// Check that files were created expect(tree.exists('src/test/file.ts')).toBeTruthy();
// Check file content const content = tree.read('src/test/file.ts', 'utf-8'); expect(content).toContain('export const test');
// You can also use snapshots expect(tree.read('src/test/file.ts', 'utf-8')).toMatchSnapshot(); });
it('should update existing files', async () => { // Run the generator await yourGenerator(tree, { name: 'test', // Add other required options });
// Check that existing files were updated const content = tree.read('src/existing-file.ts', 'utf-8'); expect(content).toContain('import { test } from'); });
it('should handle errors', async () => { // Expect the generator to throw an error in certain conditions await expect( yourGenerator(tree, { name: 'invalid', // Add options that should cause an error }), ).rejects.toThrow('Expected error message'); });});Generator 테스트를 위한 주요 사항:
createTreeWithEmptyWorkspace()를 사용하여 가상 파일 시스템 생성- generator를 실행하기 전에 필수 파일 설정
- 새 파일 생성과 기존 파일 업데이트 모두 테스트
- 복잡한 파일 내용에는 스냅샷 사용
- generator가 우아하게 실패하도록 오류 조건 테스트
@aws/nx-plugin에 Generator 기여하기
섹션 제목: “@aws/nx-plugin에 Generator 기여하기”ts#nx-generator를 사용하여 @aws/nx-plugin 내에서 generator를 스캐폴딩할 수도 있습니다.
이 generator를 저희 리포지토리에서 실행하면 다음 파일이 생성됩니다:
디렉터리packages/nx-plugin/src/<name>/
- schema.json Schema for input to your generator
- schema.d.ts TypeScript types for your schema
- generator.ts Generator implementation
- generator.spec.ts Tests for your generator
디렉터리docs/src/content/docs/guides/
- <name>.mdx Documentation page for your generator
- packages/nx-plugin/generators.json Updated to include your generator
- packages/nx-plugin/sdk/<prefix>.ts Updated to expose your generator from the SDK (for
ts#andpy#generators)
그런 다음 generator 구현을 시작할 수 있습니다.