Angular Schematics

Santosh Yadav

GDE for Angular, GitHub Star, Auth0 Ambassador

Writer AngularInDepth, Software Consultant

 

twitter.com/SantoshYadavDev

github.com/SantoshYadavDev

https://www.linkedin.com/in/yadavsantosh/

santoshyadav.dev

 

Schematics

Automate file creation/modification

Automate creating application/libraries

Automate Installation

Writing Custom Schematics

Rule

Tree

SchematicContext

Action

npm install -g @angular-devkit/schematics-cli

schematics blank --name=ng-add
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';


// You don't have to export the function as default. You can also have more than one rule factory
// per file.
export function ngAdd(_options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
    _context.addTask(new NodePackageInstallTask());

    //add a new file
    tree.create('index.ts',`console.log('Schematics is amazing')`);

    //read a file
    const fileData= tree.read('index.ts') || '';
    _context.logger.info(fileData?.toString());

    //overwrite a file
    tree.overwrite('index.ts',`console.log('schematics is great')`)
    _context.logger.info(fileData?.toString());

    //delete a file 
    tree.delete('index.ts');
    
    return tree;
  };
}

generate

import { Tree } from "@angular-devkit/schematics/src/tree/interface";
import { Rule, apply, url, applyTemplates, chain, branchAndMerge, mergeWith, SchematicContext } from "@angular-devkit/schematics";
import { strings } from "@angular-devkit/core";


export function generate(_options: any): Rule {
    return (tree: Tree, context: SchematicContext) => {
        const template = apply(url('./files'), [
            applyTemplates({
                ...strings, 
                ..._options 
            })
        ])

        return chain([
            branchAndMerge(mergeWith(template))
        ])(tree, context);
    }
}

generate/index.ts

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "ng-add": {
      "description": "A blank schematic.",
      "factory": "./ng-add/index#ngAdd"
    },
    "generate": {
      "description": "Generate schematic.",
      "factory": "./generate/index#generate"
    }
  }
}

collection.json

{
    "properties": {
        "name": {
            "type": "string",
            "minLength": 1,
            "default": "world",
            "x-prompt": "What is your name?"
        },
        "useColor": {
            "type": "boolean",
            "x-prompt": "Would you like the response in color?"
        }
    }
}

schema.json

 "schematics": "./src/collection.json",

package.json

// will not make any changes as debug is always false
schematcs .:ng-add

// will make actual changes
schematics .:ng-add --debug false


// test generate schematics
schematics .:generate --name test --debug false

Test Schematics

References

https://angular.io/guide/schematics

https://medium.com/@tomastrajan/total-guide-to-custom-angular-schematics-5c50cf90cdb4

https://indepth.dev/posts/1323/angular-schematics-from-0-to-publishing-your-own-library-i