Nx Generator Generator
Thêm một Nx Generator vào dự án TypeScript, giúp bạn tự động hóa các tác vụ lặp đi lặp lại như tạo khung các component hoặc thực thi các cấu trúc dự án cụ thể.
Cách sử dụng
Phần tiêu đề “Cách sử dụng”Tạo một Generator
Phần tiêu đề “Tạo một Generator”Bạn có thể tạo một generator theo hai cách:
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-generatorBạn cũng có thể thực hiện chạy thử để xem những tệp nào sẽ bị thay đổi
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- Cài đặt Nx Console VSCode Plugin nếu bạn chưa cài đặt
- Mở Nx Console trong VSCode
- Nhấp
Generate (UI)trong phần "Common Nx Commands" - Tìm kiếm
@aws/nx-plugin - ts#nx-generator - Điền các tham số bắt buộc
- Nhấp
Generate
Tùy chọn
Phần tiêu đề “Tùy chọn”| Tham số | Kiểu | Mặc định | Mô tả |
|---|---|---|---|
| project Bắt buộc | string | - | Dự án TypeScript để thêm generator vào. Chúng tôi khuyến nghị sử dụng generator ts#nx-plugin để tạo dự án này. |
| name Bắt buộc | string | - | Tên generator |
| description | string | - | Mô tả về generator của bạn |
| directory | string | - | Thư mục trong thư mục nguồn của dự án plugin để thêm generator vào (mặc định: <name>) |
| preferInstallDependencies | boolean | true | Có nên cài đặt các dependencies sau khi generator chạy hay không. Đặt thành false để trì hoãn việc cài đặt khi chạy nhiều generator liên tiếp (việc cài đặt vẫn sẽ chạy nếu cần thiết để các generator tiếp theo có thể tính toán Nx project graph); cài đặt một lần vào cuối. |
Kết quả đầu ra của Generator
Phần tiêu đề “Kết quả đầu ra của Generator”Generator sẽ tạo các tệp dự án sau trong project đã cho:
Thư mụcsrc/<name>/
- schema.json Schema cho đầu vào của generator của bạn
- schema.d.ts Các kiểu TypeScript cho schema của bạn
- generator.ts Triển khai generator cơ bản
- generator.spec.ts Các bài kiểm tra cho generator của bạn
- README.md Tài liệu cho generator của bạn
- generators.json Cấu hình Nx để định nghĩa các generator của bạn
- package.json Được tạo hoặc cập nhật để thêm mục “generators”
- tsconfig.json Được cập nhật để sử dụng CommonJS
Sửa đổi dự án
Generator này sẽ cập nhật project đã chọn để sử dụng CommonJS, vì Nx Generators hiện chỉ hỗ trợ CommonJS (tham khảo vấn đề GitHub này để biết về hỗ trợ ESM).
Local Generators
Phần tiêu đề “Local Generators”Chọn dự án nx-plugin cục bộ của bạn khi chạy generator ts#nx-generator, và chỉ định tên cùng với thư mục và mô tả tùy chọn.
Định nghĩa Schema
Phần tiêu đề “Định nghĩa Schema”Tệp schema.json định nghĩa các tùy chọn mà generator của bạn chấp nhận. Nó tuân theo định dạng JSON Schema với các phần mở rộng đặc thù của Nx.
Cấu trúc cơ bản
Phần tiêu đề “Cấu trúc cơ bản”Một tệp schema.json có cấu trúc cơ bản như sau:
{ "$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"]}Ví dụ đơn giản
Phần tiêu đề “Ví dụ đơn giản”Đây là một ví dụ đơn giản với một vài tùy chọn cơ bản:
{ "$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"]}Lời nhắc tương tác (CLI)
Phần tiêu đề “Lời nhắc tương tác (CLI)”Bạn có thể tùy chỉnh các lời nhắc được hiển thị khi chạy generator của bạn qua CLI bằng cách thêm thuộc tính x-prompt:
"name": { "type": "string", "description": "Component name", "x-prompt": "What is the name of your component?"}Đối với các tùy chọn boolean, bạn có thể sử dụng lời nhắc yes/no:
"withTests": { "type": "boolean", "description": "Whether to generate test files", "x-prompt": "Would you like to generate test files?"}Lựa chọn thả xuống
Phần tiêu đề “Lựa chọn thả xuống”Đối với các tùy chọn có một tập hợp lựa chọn cố định, sử dụng enum để người dùng có thể chọn từ một trong các tùy chọn.
"style": { "type": "string", "description": "The styling approach to use", "enum": ["css", "scss", "styled-components", "none"], "default": "css"}Thả xuống lựa chọn dự án
Phần tiêu đề “Thả xuống lựa chọn dự án”Một mẫu phổ biến là cho phép người dùng chọn từ các dự án hiện có trong workspace:
"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"}Thuộc tính x-dropdown: "projects" cho Nx biết để điền vào thả xuống với tất cả các dự án trong workspace.
Đối số vị trí
Phần tiêu đề “Đối số vị trí”Bạn có thể cấu hình các tùy chọn để được truyền dưới dạng đối số vị trí khi chạy generator từ dòng lệnh:
"name": { "type": "string", "description": "Component name", "x-priority": "important", "$default": { "$source": "argv", "index": 0 }}Điều này cho phép người dùng chạy generator của bạn như nx g your-generator my-component thay vì nx g your-generator --name=my-component.
Thiết lập mức độ ưu tiên
Phần tiêu đề “Thiết lập mức độ ưu tiên”Sử dụng thuộc tính x-priority để chỉ ra các tùy chọn nào quan trọng nhất:
"name": { "type": "string", "description": "Component name", "x-priority": "important"}Các tùy chọn có thể có mức độ ưu tiên là "important" hoặc "internal". Điều này giúp Nx sắp xếp các thuộc tính trong Nx VSCode extension và Nx CLI.
Giá trị mặc định
Phần tiêu đề “Giá trị mặc định”Bạn có thể cung cấp giá trị mặc định cho các tùy chọn:
"directory": { "type": "string", "description": "Directory where the component will be created", "default": "src/components"}Thông tin thêm
Phần tiêu đề “Thông tin thêm”Để biết thêm chi tiết về schemas, tham khảo tài liệu Nx Generator Options.
Các kiểu TypeScript với schema.d.ts
Phần tiêu đề “Các kiểu TypeScript với schema.d.ts”Cùng với schema.json, generator tạo một tệp schema.d.ts cung cấp các kiểu TypeScript cho các tùy chọn generator của bạn:
export interface YourGeneratorSchema { name: string; directory?: string; withTests?: boolean;}Interface này được sử dụng trong triển khai generator của bạn để cung cấp type safety và code completion:
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; // ...}Triển khai một Generator
Phần tiêu đề “Triển khai một Generator”Sau khi tạo generator mới như trên, bạn có thể viết triển khai của mình trong generator.ts.
Một generator là một hàm biến đổi một hệ thống tệp ảo (Tree), đọc và ghi các tệp để thực hiện các thay đổi mong muốn. Các thay đổi từ Tree chỉ được ghi vào đĩa sau khi generator hoàn thành thực thi, trừ khi nó được chạy ở chế độ “dry-run”. Một generator trống trông như sau:
export const myGenerator = async (tree: Tree, options: MyGeneratorSchema) => { // Use the tree to apply changes};
export default myGenerator;Dưới đây là một số thao tác phổ biến bạn có thể muốn thực hiện trong generator của mình:
Đọc và ghi tệp
Phần tiêu đề “Đọc và ghi tệp”// 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}Tạo tệp từ Templates
Phần tiêu đề “Tạo tệp từ Templates”Bạn có thể tạo tệp với tiện ích generateFiles từ @nx/devkit. Điều này cho phép bạn định nghĩa các template theo cú pháp EJS, và thay thế các biến.
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 },);Chuyển đổi mã với GritQL
Phần tiêu đề “Chuyển đổi mã với GritQL”Bạn có thể sử dụng GritQL để tìm kiếm và chuyển đổi mã nguồn một cách khai báo trong các generator của bạn. GritQL hỗ trợ nhiều ngôn ngữ bao gồm TypeScript, JavaScript, Python, HCL (Terraform), và nhiều hơn nữa — vì vậy bạn có thể sử dụng cùng một cú pháp mẫu trên toàn bộ stack của mình.
Nx Plugin for AWS cung cấp hai helper:
applyGritQL(tree, filePath, pattern)— áp dụng một mẫu viết lại GritQL vào một tệp và trả vềPromise<boolean>cho biết liệu có thay đổi nào được thực hiện hay khôngmatchGritQL(tree, filePath, pattern)— kiểm tra xem một mẫu GritQL có khớp ở bất kỳ đâu trong tệp hay không và trả về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}Các mẫu GritQL cũng hoạt động trên các tệp không phải TypeScript. Thêm tiền tố language <name> vào mẫu của bạn để nhắm đến các ngôn ngữ khác:
// Python: replace print statements with logging callsawait applyGritQL( tree, 'src/handler.py', 'language python\n`print($msg)` => `logger.info($msg)`',);Các mẫu GritQL sử dụng các đoạn mã được phân tách bằng backtick với $metavariables làm ký tự đại diện. Sử dụng => cho việc viết lại và mệnh đề where cho các điều kiện.
Thêm Dependencies
Phần tiêu đề “Thêm Dependencies”import { addDependenciesToPackageJson } from '@nx/devkit';
// Add dependencies to package.jsonaddDependenciesToPackageJson( tree, { 'new-dependency': '^1.0.0', }, { 'new-dev-dependency': '^2.0.0', },);Định dạng các tệp được tạo
Phần tiêu đề “Định dạng các tệp được tạo”import { formatFilesInSubtree } from '@aws/nx-plugin/sdk/utils/format';
// Format all files that were modifiedawait formatFilesInSubtree(tree, 'optional/path/to/format');Đọc và cập nhật các tệp JSON
Phần tiêu đề “Đọc và cập nhật các tệp 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;});Mở rộng một Generator từ Nx Plugin for AWS
Phần tiêu đề “Mở rộng một Generator từ Nx Plugin for AWS”Bạn có thể import các generator từ Nx Plugin for AWS, và mở rộng hoặc kết hợp chúng theo ý muốn, ví dụ bạn có thể muốn tạo một generator xây dựng dựa trên một dự án TypeScript:
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 Generators
Phần tiêu đề “OpenAPI Generators”Bạn có thể sử dụng và mở rộng các generator mà chúng tôi sử dụng cho các TypeScript client và hook theo cách tương tự như trên:
import { openApiTsClientGenerator } from '@aws/nx-plugin/sdk/open-api';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { await openApiTsClientGenerator(tree, { ... });
// Add additional files here};Chúng tôi cũng cung cấp một phương thức cho phép bạn xây dựng một cấu trúc dữ liệu có thể được sử dụng để lặp qua các thao tác trong một đặc tả OpenAPI và do đó tạo mã của riêng bạn, ví dụ:
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, );};Điều này sau đó cho phép bạn viết các template như:
export const myOperationNames = [<%_ allOperations.forEach((op) => { _%> '<%- op.name %>',<%_ }); _%>];Tham khảo codebase trên GitHub để biết thêm các ví dụ template phức tạp hơn.
Chạy Generator của bạn
Phần tiêu đề “Chạy Generator của bạn”Bạn có thể chạy generator của mình theo hai cách:
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-generatorBạn cũng có thể thực hiện chạy thử để xem những tệp nào sẽ bị thay đổi
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- Cài đặt Nx Console VSCode Plugin nếu bạn chưa cài đặt
- Mở Nx Console trong VSCode
- Nhấp
Generate (UI)trong phần "Common Nx Commands" - Tìm kiếm
@my-project/nx-plugin - my-generator - Điền các tham số bắt buộc
- Nhấp
Generate
Kiểm tra Generator của bạn
Phần tiêu đề “Kiểm tra Generator của bạn”Các bài kiểm tra đơn vị cho các generator rất đơn giản để triển khai. Đây là một mẫu điển hình:
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'); });});Các điểm chính để kiểm tra các generator:
- Sử dụng
createTreeWithEmptyWorkspace()để tạo một hệ thống tệp ảo - Thiết lập bất kỳ tệp tiên quyết nào trước khi chạy generator
- Kiểm tra cả việc tạo các tệp mới và cập nhật các tệp hiện có
- Sử dụng snapshot cho nội dung tệp phức tạp
- Kiểm tra các điều kiện lỗi để đảm bảo generator của bạn thất bại một cách uyển chuyển
Đóng góp Generators cho @aws/nx-plugin
Phần tiêu đề “Đóng góp Generators cho @aws/nx-plugin”Bạn cũng có thể sử dụng ts#nx-generator để tạo khung một generator trong @aws/nx-plugin.
Khi generator này được chạy trong repository của chúng tôi, nó sẽ tạo các tệp sau cho bạn:
Thư mụcpackages/nx-plugin/src/<name>/
- schema.json Schema cho đầu vào của generator của bạn
- schema.d.ts Các kiểu TypeScript cho schema của bạn
- generator.ts Triển khai generator
- generator.spec.ts Các bài kiểm tra cho generator của bạn
Thư mụcdocs/src/content/docs/guides/
- <name>.mdx Trang tài liệu cho generator của bạn
- packages/nx-plugin/generators.json Được cập nhật để bao gồm generator của bạn
- packages/nx-plugin/sdk/<prefix>.ts Được cập nhật để cung cấp generator của bạn từ SDK (cho các generator
ts#vàpy#)
Sau đó bạn có thể bắt đầu triển khai generator của mình.