3

I need assistance in calling an ng add for an external angular schematic. (I'm trying to add ng-momentum: https://github.com/BottleRocketStudios/ng-momentum) I am trying to call "ng add ng-momentum" from a custom CLI, but I've run into issues where the module "ng-momentum" can't be found.

I've tried calling the externalSchematic method from @angular-devkit/schematics in several different ways, but something is missing.

Some different implementations that I've tried:

return chain([
  externalSchematic('ng-momentum', 'scaffold', { 
   project: options.project,
 })

and

return chain([
  externalSchematic('ng-momentum', 'ng-add', {
  }),
  externalSchematic('ng-momentum', 'scaffold', {
    spec: false,
    force: true,
  })

as well as

return chain([
  externalSchematic('ng', 'add', {
   project: options.project,
   package: 'ng-momentum',
 })

but I always get the same error as described below

Reproduction Steps
1) Run "npm i @lcu/cli -g" to install the custom CLI
2) Create a new empty folder, navigate to it
3) Run command "lcu init". Name the scope "@scope" and the workspace "test"
4) In the same folder, run command "lcu proj newProject" Select "App". Select "Momentum"

Expected behavior: Following the steps from ng-momentum, if I create a new angular project (ng new newProject) and then run the ng add (ng add ng-momentum) outside of the CLI, I get a new angular project and ng-momentum app.

Actual behavior: I receive the following error: "Could not find module "ng-momentum" from "C:\wherever\your\project\is".

It seems like I'm missing something, but not entirely sure what. Please let me know if additional info is needed, or if there are any questions.

Thank you in advance!

TrevorR
  • 31
  • 4

2 Answers2

3

I'm fall in the same problem and find a solution for it.

The issue is that to run ng-momentum:ng-add schematic you will need to install the package before it, as well as ng add do it for us.

So, you will need to break your schematics in two fases: Install Dependencies and Your actual rule.

Take a look on a Rule that ask for the package installation and queue your Rule.


export functions dependencies(options): Rule: Rule {
    return (_tree: Tree, context: SchematicContext) => {
        const installTaskId = context.addTask(new NodePackageInstallTask({
            packageName: 'ng-momentum'
        }));

        context.addTask(new RunSchematicTask('after-dependencies', options), [installTaskId]);
    }
}

Don’t be afraid, your user will not see this, if you config your collections like this.


{
    "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
    "schematics": {
        "your-rule": {
            "factory": "./what-ever/index#dependencies",
            "schema": "./what-ever/schema.json"
        },
        "after-dependencies": {
            "factory": "./what-ever/index#yourRule",
            "schema": "./what-ever/schema.json",
            "private": true,
        }
    }
}


jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
0

I struggled with calling an externalSchematic from a custom add schematic, and actually, the library you want to call from your ng add MUST be installed locally in your root package.json.

The externalSchematic call is looking for package.json, and unless it's installed in the root schematic project, it won't work.

I hope it's related to this issue !

Alain Boudard
  • 768
  • 6
  • 16