생성기 기여하기
@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 APIyarn 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 APInpx 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 APIbunx 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-runyarn 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-runnpx 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-runbunx 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에 프로시저를 추가하려면 두 가지가 필요합니다:
- 새 프로시저용 타입스크립트 파일 생성
- 라우터에 프로시저 추가
새 프로시저 생성
섹션 제목: “새 프로시저 생성”새 프로시저용 타입스크립트 파일을 생성하기 위해 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, 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;라우터에 프로시저 추가
섹션 제목: “라우터에 프로시저 추가”다음으로 제너레이터가 새 프로시저를 라우터에 연결하도록 합니다. 이는 사용자의 소스 코드를 읽고 업데이트하는 것을 의미합니다!
GritQL을 사용하여 선언적으로 소스 코드를 검색하고 변환합니다. addDestructuredImport 헬퍼는 명명된 임포트를 추가하고, applyGritQL은 GritQL 패턴을 적용하여 라우터의 객체 리터럴에 프로시저를 추가합니다.
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 { 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(__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가 있는 테스트 프로젝트 생성
섹션 제목: “tRPC API가 있는 테스트 프로젝트 생성”별도의 디렉토리에서 새 테스트 워크스페이스를 생성합니다:
npx create-nx-workspace@22.6.5 trpc-generator-test --pm=pnpm --preset=@aws/nx-plugin --ci=skip --analytics=false --aiAgentsnpx create-nx-workspace@22.6.5 trpc-generator-test --pm=yarn --preset=@aws/nx-plugin --ci=skip --analytics=false --aiAgentsnpx create-nx-workspace@22.6.5 trpc-generator-test --pm=npm --preset=@aws/nx-plugin --ci=skip --analytics=false --aiAgentsnpx create-nx-workspace@22.6.5 trpc-generator-test --pm=bun --preset=@aws/nx-plugin --ci=skip --analytics=false --aiAgents다음으로 프로시저를 추가할 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-interactiveyarn nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactivenpx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactivebunx 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-runyarn nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-runnpx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-runbunx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-run로컬 Nx Plugin for AWS 연결
섹션 제목: “로컬 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새 제너레이터 실행
섹션 제목: “새 제너레이터 실행”새 제너레이터를 실행해 봅니다:
- 설치 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#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성공하면 새 프로시저가 생성되고 router.ts의 라우터에 프로시저가 추가됩니다.
연습 문제
섹션 제목: “연습 문제”여기까지 완료했고 Nx 제너레이터를 실험할 시간이 남았다면, 프로시저 제너레이터에 추가할 기능에 대한 제안 사항입니다:
1. 중첩 작업
섹션 제목: “1. 중첩 작업”다음을 통해 중첩 라우터를 지원하도록 제너레이터를 업데이트해 보세요:
procedure입력에 점 표기법 허용 (예:games.query)- 역방향 점 표기법 기반 프로시저 이름 생성 (예:
queryGames) - 적절한 중첩 라우터 추가 (또는 이미 존재하는 경우 업데이트!)
2. 유효성 검사
섹션 제목: “2. 유효성 검사”제너레이터는 사용자가 tRPC API가 아닌 project를 선택하는 것과 같은 잠재적 문제를 방어해야 합니다. 이에 대한 예시로 connection 제너레이터를 살펴보세요.
3. 단위 테스트
섹션 제목: “3. 단위 테스트”제너레이터에 대한 단위 테스트를 작성하세요. 구현이 매우 간단하며 대부분 다음과 같은 일반적인 흐름을 따릅니다:
createTreeUsingTsSolutionSetup()을 사용하여 빈 워크스페이스 트리 생성- 트리에 이미 존재해야 하는 파일 추가 (예: tRPC 백엔드의 경우
project.json및src/router.ts) - 테스트 중인 제너레이터 실행
- 트리에 예상된 변경 사항이 적용되었는지 검증
4. 종단 간 테스트
섹션 제목: “4. 종단 간 테스트”현재 모든 제너레이터를 실행하고 빌드가 성공하는지 확인하는 단일 “smoke test”가 있습니다. 이를 새 제너레이터를 포함하도록 업데이트해야 합니다.
기여를 가속화하기 위한 일반 지침
섹션 제목: “기여를 가속화하기 위한 일반 지침”이 섹션에는 Nx Plugin for AWS 작업 시 도움이 될 수 있는 일반 지침이 포함되어 있습니다.
실제 프로젝트에서 역방향으로 작업하기
섹션 제목: “실제 프로젝트에서 역방향으로 작업하기”새로운 제너레이터를 구축하거나 기존 제너레이터에 기능/수정 사항을 추가하는 유용한 방법은 _먼저 실제로 구축하는 것_입니다. 이렇게 하면 아이디어를 검증하고 필요한 기능을 달성하기 위해 빠르게 반복할 수 있습니다. 원하는 결과를 확정한 후에 제너레이터를 업데이트할 수 있습니다.
실제로 이 프로세스는 다음과 같이 진행될 수 있습니다:
-
새 워크스페이스 생성
Terminal window npx create-nx-workspace@22.6.5 my-project --pm=pnpm --preset=@aws/nx-plugin --ci=skip --analytics=false --aiAgentsTerminal window npx create-nx-workspace@22.6.5 my-project --pm=yarn --preset=@aws/nx-plugin --ci=skip --analytics=false --aiAgentsTerminal window npx create-nx-workspace@22.6.5 my-project --pm=npm --preset=@aws/nx-plugin --ci=skip --analytics=false --aiAgentsTerminal window npx create-nx-workspace@22.6.5 my-project --pm=bun --preset=@aws/nx-plugin --ci=skip --analytics=false --aiAgents -
새 제너레이터/기능/수정 사항의 전제 조건이 될 수 있는 제너레이터 실행
-
변경 사항 커밋 (
git commit) -
원하는 변경 사항을 만들고 필요에 따라 테스트
-
변경 사항의
git diff를 사용하여 Nx Plugin for AWS에 어떤 변경 사항을 적용해야 하는지 파악 -
제너레이터가 필요한 변경 사항을 제공하는지 확인하기 위해 최종 종단 간 테스트 수행 (
@aws/nx-plugin연결)