What if our library were to include a schematic?
Angular CLI: 9.0.7
Node: 12.14.1
OS: win32 x64
Angular: 9.0.7
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes
Package Version
------------------------------------------------------------
@angular-devkit/architect 0.900.7
@angular-devkit/build-angular 0.900.7
@angular-devkit/build-ng-packagr 0.900.7
@angular-devkit/build-optimizer 0.900.7
@angular-devkit/build-webpack 0.900.7
@angular-devkit/core 9.0.7
@angular-devkit/schematics 9.0.7 <= Must exist
@ngtools/webpack 9.0.7
@schematics/angular 9.0.7
@schematics/update 0.900.7
ng-packagr 9.1.5
rxjs 6.5.5
typescript 3.7.5
webpack 4.41.2
We started...
cd projects
// this requires an environment variable
// pointing to global node_modules bin folder
schematics blank --schematics --name=schematic
Make sure the outer package.json file and the schematics.json have
same versioning.
Auto-Generated Code
ng build schematics
An unhandled exception occurred: Project 'schematics' does not support the 'build' target.
See "C:\src\AppData\Local\Temp\ng-WJqucJ\angular-errors.log" for further details.
Set up a console.log
ng build schematics
{
archtectCommand: {
projectName: 'schematics',
targetProjectNames: [ 'projecty', 'demo' ]
}
}
// ok, the target project names does not include our schematics project.
// the angular.json file had no entry for this project!
This doesn't work either
// moved it inside the library
C:\src\projectx\projects\projecty\src\lib> schematics blank --schematics --name=schematics
Back Up
// we tried this command again in different folder.
// the same folder as first try
C:\src\projectx\projects> schematics blank --name=schematics
cd .\schematics
npm install
npm run build
This worked because we were calling the build in the schematics folder, using npm instead of ng. But there was a compiler error.
src/schematics/index_spec.ts:12:25 - error TS2339: Property 'runSchematic' does not exist on type 'SchematicTestRunner'.
12 const tree = runner.runSchematic('schematics', {}, Tree.empty());
Never argue with a compiler...
There it is; the new async version. This means the schematic itself is wrong... The angular/cli doesn't generate schematics correctly. Easy to fix.
This fixes the error:
import { Tree } from '@angular-devkit/schematics';
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
import * as path from 'path';
const collectionPath = path.join(__dirname, '../collection.json');
describe('schematics', () => {
it('works', async() => {
const runner = new SchematicTestRunner('schematics', collectionPath);
const tree = await runner.runSchematicAsync('schematics', {}, Tree.empty());
tree.subscribe(tree=>{
console.log(tree);
expect(tree.files).toEqual([]);
});
});
});
Our first glimpse into a schematic tree!
UnitTestTree {
_other: HostTree {
_backend: Empty { capabilities: [Object] },
_id: -1,
_ancestry: Set {},
_dirCache: Map {},
_record: CordHost {
_cache: [Map],
_watchers: Map {},
_back: [SafeReadonlyHost],
_filesToCreate: Set {},
_filesToRename: Map {},
_filesToRenameRevert: Map {},
_filesToDelete: Set {},
_filesToOverwrite: Set {}
},
_recordSync: SyncDelegateHost { _delegate: [CordHost] }
}
Top comments (2)
I think this code snippet will not render. you need either add
toPromise()
to the runSchematicAsync:or remove async/await:
Hi John Peters,
Your tips are very useful
Thanks for sharing