5

I'm creating some custom schematics that will help us spin up angular library projects quickly. Given that, I don't want developers to have to have a checklist of ng ... commands they have to run to get a library up and running, I'd like to just have a single command that sets up a workspace, puts a library in it, makes some customizations (swap in jest for karma, add some CI config, etc).

My approach in doing this is to create a schematic that starts with an empty tree, then calls the ng-new schematic from @schematics/angular, via externalSchematic() then chains the library schematic from the same package followed by a number of our custom schematics to make the customizations.

My reasons for wanting to use externalSchematic() as opposed to just copying all the external schematics' code into my schematics project is so that when @schematics/angular is updated, I can incorporate those updates by just doing yarn upgrade-interactive and find and resolve any issues by running the test suite. Eventually we can automate this with CI.

I've created a small self contained example reproducing my error here: https://github.com/matt328/ng-schematics-test

Steps to reproduce:

git clone
npm install
npm run build
schematics ng-schematics-test:my-full-schematic --name=test-schematic

When I run the schematic, it reports Invalid source: undefined.

Here

https://github.com/matt328/ng-schematics-test/blob/master/src/my-full-schematic/index.ts#L30

is where I'm using externalSchematic() to call ng-new.

I've did some digging into the source and found it is caused by a few of the angular schematics' having

"$default": {
  "$source": "projectName"
}

in their schemas. The error is a result of projectName not being defined.

What else has to be done in order to be able to call ng-new with externalSchema()? Is this approach valid, or is there some other way to do this?

Matt
  • 823
  • 1
  • 8
  • 17

2 Answers2

2

Back in early February I was able to get a working version of the externalSchematics command from this demo working. When I tried to replicate my previous results today, I received the same error as you (for ng-new, component, and interface when I tried to run the command from within the schematics project.

However, when I created a new Angular project and created a symlink to the schematic project, I was able to successfully generate a component and interface in the Angular project. Have not yet succeeded with ng-new since the node_modules mapping isn't quite as simple (it did prompt me for some required parameters, version and name before throwing a missing module error, which I suppose may be construed as progress).

ericksoen
  • 821
  • 8
  • 14
  • Hey @ericksoen! Can you, plese, share your dependencies from the new project? Even working with a fresh installed environment it still not working. Thanks! – GRGodoi Jun 04 '18 at 22:49
  • Here's a [repo link to a paired down version of my schematic project](https://github.com/ericksoen/schematic-demo). It has a single passing test for a `ng-new` command. I also validated that if you create a symlink to the project root, that you can use it to initialize new projects using `ng new project-name --collection demo-schematic` – ericksoen Jun 11 '18 at 14:33
1

This one took me a while:

It seems that you must run any schematic that extends an @schematics/angular schematic inside an real angular project. To do so, do the following:

  • $ cd <path to an angular project>
  • $ npm link <path to your custom schematics project>
  • $ ng g <schematics-collection-name>:<schematic-name> [params]

this should work, as your extended @schematics/angular schematic now runs inside an angular project and is able to get a correct source.

Also note: Running it with $ schematics <collection-name>:<schematics-name> will lead to the same undefined error!

Hope this helps

jlang
  • 929
  • 11
  • 32