-
Notifications
You must be signed in to change notification settings - Fork 11.9k
Description
🐞 Bug report
Command (mark with an x
)
- [ x ] generate
- [ x ] add
- [ x ] update
Is this a regression?
Yes, it used to work in Angular <= 8.x
Description
I have a library "@mycompany/mylib" and a separate package containing its schematics called "@mycompany/mylib-schematics".
I used to have this entry in the library's package.json
file:
"schematics": "@mycompany/mylib-schematics/collection.json"
And this worked fine.
When executing, for example ng generate @mycompany/mylib:foo
it would correctly resolve the collection.json file residing in "node_modules/@mycompany/mylib-schematics" and execute the schematic.
With Angular 9 this does not work anymore. I can no longer specify a package name in the "schematics" property of the package.json file. The path specified there is always resolved relative to the package.json location. I can make it work again if I change it to this:
"schematics": "../mylib-schematics/collection.json"
The problem is within packages/angular_devkit/schematics/tools/node-module-engine-host.ts
:
protected _resolveCollectionPath(name: string): string {
let collectionPath: string | undefined = undefined;
if (name.startsWith('.') || name.startsWith('/')) {
name = resolve(name);
}
if (extname(name)) {
// When having an extension let's just resolve the provided path.
collectionPath = require.resolve(name, { paths: this.paths });
} else {
const packageJsonPath = require.resolve(join(name, 'package.json'), { paths: this.paths });
const { schematics } = require(packageJsonPath);
if (!schematics || typeof schematics !== 'string') {
throw new NodePackageDoesNotSupportSchematics(name);
}
// !!!
// the below line is wrong: it should only try to resolve it that way if the path starts with '.' or '/'
// (i.e. when dealing with a relative or absolute path)
// otherwise it should use require.resolve() like above
// !!!
collectionPath = resolve(dirname(packageJsonPath), schematics);
}
🔬 Minimal Reproduction
As described above, create a library and add a "collections" property to its package.json that points to another node_module, then try to "ng generate".
package.json
of "@mycompany/mylib":
"schematics": "@mycompany/mylib-schematics/collection.json"
ng generate @mycompany/mylib:foo
:
An unhandled exception occurred: Collection "@mycompany/mylib" cannot be resolved.
🔥 Exception or Error
[error] Error: Collection "@mycompany/mylib" cannot be resolved.
at NodeModulesEngineHost._resolveCollectionPath (test-project/node_modules/@angular-devkit/schematics/tools/node-module-engine-host.js:55:15)
at NodeModulesEngineHost.createCollectionDescription (test-project/node_modules/@angular-devkit/schematics/tools/file-system-engine-host-base.js:109:27)
at SchematicEngine._createCollectionDescription (test-project/node_modules/@angular-devkit/schematics/src/engine/engine.js:147:40)
at SchematicEngine.createCollection (test-project/node_modules/@angular-devkit/schematics/src/engine/engine.js:140:43)
at GenerateCommand.getCollection (test-project/node_modules/@angular/cli/models/schematic-command.js:127:35)
at GenerateCommand.initialize (test-project/node_modules/@angular/cli/models/schematic-command.js:43:37)
at async GenerateCommand.initialize (test-project/node_modules/@angular/cli/commands/generate-impl.js:12:9)
at async GenerateCommand.validateAndRun (test-project/node_modules/@angular/cli/models/command.js:124:9)
at async Object.runCommand (test-project/node_modules/@angular/cli/models/command-runner.js:201:24)
at async default_1 (test-project/node_modules/@angular/cli/lib/cli/index.js:62:31)
🌍 Your Environment
Angular CLI: 9.0.2
Node: 12.14.1
OS: darwin x64
Angular: 9.0.1
... animations, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router
Ivy Workspace: Yes
Package Version
------------------------------------------------------------
@angular-devkit/architect 0.900.2
@angular-devkit/build-angular 0.900.2
@angular-devkit/build-optimizer 0.900.2
@angular-devkit/build-webpack 0.900.2
@angular-devkit/core 9.0.2
@angular-devkit/schematics 9.0.2
@angular/cdk 9.0.0
@angular/cli 9.0.2
@angular/material 9.0.0
@angular/material-moment-adapter 9.0.0
@ngtools/webpack 9.0.2
@schematics/angular 9.0.2
@schematics/update 0.900.2
rxjs 6.5.3
typescript 3.7.5
webpack 4.41.2