angularnrwl-nxangular-schematics

Extending NX generate component


In my Monorepo, there are two types of components that i am using.

  1. Is a standard component for applications, and nx g c foo works fine here.
  2. Is a library component for a library. Here, I exclusively use secondary entry points. So a component always has an index.ts, a public_api.ts, a bar.module.ts and a package.json file.

My question is, how could I extend the standard functionality of the nx g c foo, so that it automatically creates these files?


Solution

  • You probably want to write your own schematics collection.
    Please check documentation, some nice articles and sources.
    Basically your extending code from new component schematic will look like this:

    import { chain, externalSchematic, Rule } from '@angular-devkit/schematics';
    
    export default function(schema: any): Rule {
        // add your custom code here
    
        return chain([
            externalSchematic('@nrwl/schematics', 'module', {
              ...module options
            }),
            externalSchematic('@nrwl/schematics', 'component', {
              ...component options
            }),
    
            // and here
        ]);
    }
    

    UPD

    The same written using nx generators API:

    import { wrapAngularDevkitSchematic } from '@nrwl/devkit/ngcli-adapter';
    import {
      Tree,
      formatFiles,
      generateFiles,
      joinPathFragments,
      names,
    } from '@nrwl/devkit';
    // this is your custom generator schema
    import { Schema } from './models/schema.model';
    
    export default async function (tree: Tree, schema: Schema) {
      const moduleGenerator = wrapAngularDevkitSchematic(
        '@schematics/angular',
        'module'
      );
      const componentGenerator = wrapAngularDevkitSchematic(
        '@schematics/angular',
        'component'
      );
    
      // it will create a custom module for you
      await moduleGenerator(tree, {
        name: ...module name,
        project: ...project to add module,
        path: ...path to add module file,
      });
    
      // it will create a custom component for you
      await componentGenerator(tree, {
        name: ...your name,
        project: ...project to add component,
      });
    
      // it's a branch where you can add your package.json and index.ts
      // you should create template files for them in ./files folder
      generateFiles(
        tree, // the virtual file system
        joinPathFragments(__dirname, './files'), // path to the file templates
        joinPathFragments('libs/'), // destination path of the files
        {
          ...schema,
          ...names(schema.name),
          tmpl: '',
        } // config object to replace variable in file templates
      );
    
    
      return tree;
    }
    

    See their tests for more examples.