调用外部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需要显式配置来实现相同逻辑。
修改
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行为一致。可选:代码层面动态获取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]); }; }验证效果
修改配置后重新运行schematic,输入项目名称后无需指定--version,即可自动使用最新版本创建项目并添加prettier配置。
内容的提问来源于stack exchange,提问作者Iván Jiménez Luque
相关产品推荐
相关产品推荐

