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

调用外部ng-new schematic时自动获取最新版本的问题求助

问题:自定义Schematic调用ng-new时需手动指定version,如何自动使用最新版本?

我正在开发一个自定义Schematic,流程是先调用Angular原生的ng-new创建新项目,再调用自定义Schematic添加prettier配置文件。但执行时出现错误:

Data path "" must have required property 'version'.

现在必须手动添加--version="x"参数才能正常执行,想问能不能不用手动指定version,像原生ng new那样自动使用最新版本?


我的Schematic代码

import {
  chain,
  externalSchematic,
  Rule,
  schematic,
  SchematicContext,
  Tree,
} from "@angular-devkit/schematics";

import { Schema as NgNewOptions } from "@schematics/angular/ng-new/schema";

export function newProject(options: NgNewOptions): Rule {
  return async (_tree: Tree, _context: SchematicContext) => {
    const rule = externalSchematic("@schematics/angular", "ng-new", options);
    const rule2 = schematic("add-prettier-configuration", options);

    return chain([rule, rule2]);
  };
}

collection配置

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "extends": ["@schematics/angular"],
  "schematics": {
    "hello-world": {
      "description": "A blank schematic.",
      "factory": "./hello-world/index#helloWorld"
    },
    "goodbye-world": {
      "description": "A blank schematic.",
      "factory": "./goodbye-world/index#goodbyeWorld"
    },
    "add-prettier-configuration": {
      "description": "add a prettier configuration file.",
      "factory": "./add-prettier-configuration/index#addPrettierConfiguration",
      "schema": "./add-prettier-configuration/schema.json"
    },
    "new-project": {
      "description": "A blank schematic.",
      "factory": "./new-project/index#newProject",
      "schema": "./new-project/schema.json"
    }
  }
}

执行错误日志

schematics ./hello-world:new-project
Debug mode enabled by default for local collections.
? What name would you like to use for the new workspace and initial project? iuhiuh+
An error occured:
Error: Schematic input does not validate against the Schema: {"name":"iuhiuh+"}
Errors:

  Data path "" must have required property 'version'.
    at MapSubscriber.project (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\@angular-devkit\schematics\tools\schema-option-transform.js:30:27)
    at MapSubscriber._next (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\rxjs\internal\operators\map.js:49:35)
    at MapSubscriber.Subscriber.next (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\rxjs\internal\Subscriber.js:66:18)
    at ThrowIfEmptySubscriber._next (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\rxjs\internal\operators\throwIfEmpty.js:44:26)
    at ThrowIfEmptySubscriber.Subscriber.next (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\rxjs\internal\Subscriber.js:66:18)
    at TakeSubscriber._next (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\rxjs\internal\operators\take.js:54:30)
    at TakeSubscriber.Subscriber.next (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\rxjs\internal\Subscriber.js:66:18)
    at MergeMapSubscriber.notifyNext (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\rxjs\internal\operators\mergeMap.js:93:26)
    at SimpleInnerSubscriber._next (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\rxjs\internal\innerSubscribe.js:27:21)
    at SimpleInnerSubscriber.Subscriber.next (C:\Users\ijimenlu\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\rxjs\internal\Subscriber.js:66:18)

解决方法

问题出在new-project schematic的schema配置上,原生ng new会自动处理version参数的默认值,但自定义schematic需要显式配置来实现相同逻辑。

  1. 修改new-project/schema.json
    让schema继承自@schematics/angular/ng-new的schema,并给version设置latest默认值:

    {
      "$schema": "http://json-schema.org/schema",
      "extends": "@schematics/angular/ng-new/schema",
      "properties": {
        "version": {
          "type": "string",
          "default": "latest",
          "description": "The version of Angular to use."
        }
      }
    }
    

    这样用户不指定version时,会自动使用最新版本,和原生ng new行为一致。

  2. 可选:代码层面动态获取CLI版本
    如果你希望精准匹配当前Angular CLI的版本,可以在代码中动态获取:

    import { execSync } from 'child_process';
    
    export function newProject(options: NgNewOptions): Rule {
      return async (_tree: Tree, _context: SchematicContext) => {
        // 未指定version时,自动获取当前CLI版本
        if (!options.version) {
          try {
            const cliVersion = execSync('ng version --json', { encoding: 'utf-8' });
            options.version = JSON.parse(cliVersion).cli.version;
          } catch (e) {
            // 获取失败则 fallback 到 latest
            options.version = 'latest';
          }
        }
        const rule = externalSchematic("@schematics/angular", "ng-new", options);
        const rule2 = schematic("add-prettier-configuration", options);
    
        return chain([rule, rule2]);
      };
    }
    
  3. 验证效果
    修改配置后重新运行schematic,输入项目名称后无需指定--version,即可自动使用最新版本创建项目并添加prettier配置。

内容的提问来源于stack exchange,提问作者Iván Jiménez Luque

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:15:48