생성기 기여하기
@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
빈 제너레이터 생성
새 제너레이터를 packages/nx-plugin/src/trpc/procedure
에 생성합니다.
새 제너레이터 스캐폴딩을 위해 제공되는 제너레이터를 사용할 수 있습니다:
- 설치 Nx Console VSCode Plugin 아직 설치하지 않았다면
- VSCode에서 Nx 콘솔 열기
- 클릭
Generate (UI)
"Common Nx Commands" 섹션에서 - 검색
@aws/nx-plugin - ts#nx-generator
- 필수 매개변수 입력
- pluginProject: @aws/nx-plugin
- name: ts#trpc-api#procedure
- directory: trpc/procedure
- description: Adds a procedure to a tRPC API
- 클릭
Generate
pnpm nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API
yarn nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API
npx nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API
bunx nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@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 --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-run
yarn nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-run
npx nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-run
bunx nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-run
다음 파일들이 자동 생성됩니다:
디렉터리packages/nx-plugin/src/trpc/procedure
- schema.json 제너레이터 입력 스키마 정의
- schema.d.ts 스키마에 대응하는 타입스크립트 인터페이스
- generator.ts Nx가 실행할 제너레이터 함수
- generator.spec.ts 제너레이터 테스트
디렉터리docs/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 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 파일 생성
- 라우터에 프로시저 추가
새 프로시저 생성
generateFiles
유틸리티와 EJS 템플릿을 사용하여 TypeScript 파일을 생성합니다. 템플릿은 사용자 선택 옵션 기반 변수로 렌더링됩니다.
템플릿 파일 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 {}; });
템플릿에서 사용된 세 변수(procedureNameCamelCase
, procedureNameKebabCase
, procedureType
)를 generateFiles
에 전달해야 합니다. 사용자가 선택한 프로젝트의 소스 루트 경로는 프로젝트 설정에서 추출합니다.
제너레이터 코드 업데이트:
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;
라우터에 프로시저 추가
TypeScript AST 조작을 통해 라우터 소스 파일을 업데이트합니다. replace
와 destructuredImport
헬퍼를 사용합니다.
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;
제너레이터 컴파일:
pnpm nx run @aws/nx-plugin:compile
제너레이터 테스트
로컬 Nx Plugin for AWS를 기존 코드베이스에 연결하여 테스트합니다.
tRPC API 테스트 프로젝트 생성
새 테스트 워크스페이스 생성:
npx create-nx-workspace@~20.6.3 trpc-generator-test --pm=pnpm --preset=ts --ci=skip --formatter=prettier
npx create-nx-workspace@~20.6.3 trpc-generator-test --pm=yarn --preset=ts --ci=skip --formatter=prettier
npx create-nx-workspace@~20.6.3 trpc-generator-test --pm=npm --preset=ts --ci=skip --formatter=prettier
npx create-nx-workspace@~20.6.3 trpc-generator-test --pm=bun --preset=ts --ci=skip --formatter=prettier
tRPC API 생성:
- 설치 Nx Console VSCode Plugin 아직 설치하지 않았다면
- VSCode에서 Nx 콘솔 열기
- 클릭
Generate (UI)
"Common Nx Commands" 섹션에서 - 검색
@aws/nx-plugin - ts#trpc-api
- 필수 매개변수 입력
- apiName: test-api
- 클릭
Generate
pnpm nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive
yarn nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive
npx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive
bunx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive
어떤 파일이 변경될지 확인하기 위해 드라이 런을 수행할 수도 있습니다
pnpm nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-run
yarn nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-run
npx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-run
bunx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-run
로컬 Nx Plugin 연결
로컬 @aws/nx-plugin
연결:
cd path/to/trpc-generator-testpnpm link path/to/nx-plugin-for-aws/dist/packages/nx-plugin
cd path/to/trpc-generator-testyarn link path/to/nx-plugin-for-aws/dist/packages/nx-plugin
cd path/to/trpc-generator-testnpm link path/to/nx-plugin-for-aws/dist/packages/nx-plugin
cd path/to/nx-plugin-for-aws/dist/packages/nx-pluginbun linkcd path/to/trpc-generator-testbun link @aws/nx-plugin
새 제너레이터 실행
새 제너레이터 실행 시도:
- 설치 Nx Console VSCode Plugin 아직 설치하지 않았다면
- VSCode에서 Nx 콘솔 열기
- 클릭
Generate (UI)
"Common Nx Commands" 섹션에서 - 검색
@aws/nx-plugin - ts#trpc-api#procedure
- 필수 매개변수 입력
- 클릭
Generate
pnpm nx g @aws/nx-plugin:ts#trpc-api#procedure
yarn nx g @aws/nx-plugin:ts#trpc-api#procedure
npx nx g @aws/nx-plugin:ts#trpc-api#procedure
bunx nx g @aws/nx-plugin:ts#trpc-api#procedure
어떤 파일이 변경될지 확인하기 위해 드라이 런을 수행할 수도 있습니다
pnpm nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-run
yarn nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-run
npx nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-run
bunx nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-run
성공 시 새 프로시저가 생성되고 router.ts
에 추가됩니다.
연습 문제
Nx 제너레이터 실험을 위한 추가 기능 제안:
1. 중첩 작업 지원
procedure
입력에 닷 노테이션 지원 (예:games.query
)- 역방향 닷 노테이션 기반 프로시저 이름 생성 (예:
queryGames
) - 중첩 라우터 생성/업데이트
2. 유효성 검사
tRPC API가 아닌 프로젝트 선택 방지. api-connection
제너레이터 예제 참조.
3. 단위 테스트 작성
제너레이터 단위 테스트 작성:
createTreeUsingTsSolutionSetup()
로 빈 워크스페이스 트리 생성- 기존 파일 추가 (예:
project.json
,src/router.ts
) - 제너레이터 실행
- 트리 변경 사항 검증
4. E2E 테스트
현재 “smoke test”에 새 제너레이터 포함하도록 업데이트.