如何在Nx自定义生成器中合并Angular库生成器Schema?
问题
我正在开发一个Nx插件,想要扩展内置的Angular库生成器,目标是把原Angular库生成器的Schema和自定义选项合并,让生成器运行时CLI能同时提示原选项和自定义选项。
当前我的配置如下:
generators.json
{ "generators": { "init": { "factory": "./dist/generators/init/init", "schema": "./dist/generators/init/schema.json", "description": "init generator" } } }
schema.json
{ "$schema": "https://json-schema.org/schema", "$id": "Domain", "title": "", "type": "object", "properties": { "name": { "type": "string", "description": "", "$default": { "$source": "argv", "index": 0 }, "x-prompt": "What name would you like to use?" } }, "required": ["name"] }
我尝试用JSON Schema的allOf组合来合并原Schema与自定义Schema:
{ "allOf": [ { "$ref": "./node_modules/@nrwl/angular/generators/library/schema.json" }, { "type": "object", "properties": { "name": { "type": "string", "description": "Your custom name", "$default": { "$source": "argv", "index": 0 }, "x-prompt": "What name would you like to use?" }, "customOption": { "type": "string", "description": "A custom option for your extended generator", "x-prompt": "Provide your custom option" } }, "required": ["name", "customOption"] } ] }
但运行生成器时,只显示自定义选项的提示,原Angular库生成器的选项没出现。我想知道:
- 如何正确合并原Schema与自定义Schema,让生成器提示包含两类选项?
- 是否有其他扩展Nx现有生成器Schema的方法?
解决方案
1. 修复JSON Schema的allOf合并问题
你遇到的问题大概率是路径引用错误或字段覆盖导致的,按以下方式调整:
调整Schema引用与字段定义
- 改用Nx包内路径引用原Schema,避免相对路径解析问题
- 不要重复定义原Schema已有的字段(比如
name),防止覆盖原提示逻辑
{ "$schema": "http://json-schema.org/schema", "allOf": [ { "$ref": "@nrwl/angular/generators/library/schema.json" }, { "type": "object", "properties": { "customOption": { "type": "string", "description": "A custom option for your extended generator", "x-prompt": "Provide your custom option" } }, "required": ["customOption"] } ] }
确保Schema编译正常
在插件的构建配置中,确保node_modules中的JSON文件能被正确解析,或者在tsconfig.json里添加"resolveJsonModule": true配置。
2. 使用Nx生成器继承机制(更可靠)
Nx推荐通过继承现有生成器的方式扩展,既能复用原Schema,也能复用生成逻辑:
修改生成器工厂函数
在你的init生成器中导入并调用原Angular库生成器,传入所有参数:
import { libraryGenerator } from '@nrwl/angular/generators'; import { Tree, formatFiles, installPackagesTask } from '@nrwl/devkit'; export async function initGenerator(tree: Tree, schema: any) { // 调用原生成器,传递所有参数 await libraryGenerator(tree, { ...schema }); // 在这里添加你的自定义逻辑,比如修改生成文件、追加配置等 await formatFiles(tree); return () => installPackagesTask(tree); } export default initGenerator;
静态合并Schema
直接在schema.json中通过require引入原Schema并合并,避免运行时解析问题:
{ "$schema": "http://json-schema.org/schema", "$id": "Domain", "title": "Extended Angular Library Generator", "type": "object", "properties": { ...require('@nrwl/angular/generators/library/schema.json').properties, "customOption": { "type": "string", "description": "A custom option for your extended generator", "x-prompt": "Provide your custom option" } }, "required": [ ...require('@nrwl/angular/generators/library/schema.json').required, "customOption" ] }
3. 使用Nx Schema扩展工具
利用@nrwl/devkit提供的extendSchema工具函数,在代码中动态扩展Schema,再导出为schema.json(可通过构建脚本自动生成):
import { extendSchema } from '@nrwl/devkit'; import librarySchema from '@nrwl/angular/generators/library/schema.json'; const extendedSchema = extendSchema(librarySchema, { properties: { customOption: { type: 'string', description: 'A custom option for your generator', x-prompt: 'Enter your custom option' } }, required: [...librarySchema.required, 'customOption'] }); // 将extendedSchema写入到dist/generators/init/schema.json
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

