You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 18:56:00