0.0.1 • Published 1 year ago

angular-cli-hooks v0.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Angular CLI hooks

This small package hooks into native Angular CLI builders. With it, you can...

  • ... run code before Angular CLI invocates native builders
  • ... and/or override invocations
  • ... and/or run code after Angular CLI emits BuilderOutput

A few examples include

  • Running eslint before ng build runs
  • Using jest over jasmine when running ng test
  • Starting a mock server with ng serve

Usage

Step 1 - creating a hook package

First, you need to create a package of hooks. To, for example, run ESLint before ng build, add a hook to build and a before-function. The before-function can return either Observable, Promise or a sync value.

Then, to make the hook configurable, use the schema-property to add a JsonSchema for any configurations. When installing @berglund/angular-cli-hooks, this schema is merged with the native Angular CLI builder schema.

Adding a JsonSchema makes both the hook configuration and the native builder configuration available when implementing the hook. Both are also listed when running ng build --help 🥳.

// index.ts in @berglund/builder-hooks

import { BuilderOutput } from '@angular-devkit/architect';
import { hook } from '@berglund/angular-cli-hooks';
import { ESLint } from 'eslint';

export default [
  hook({
    name: 'build',
    schema: {
      properties: {
        failOnLintErrors: {
          type: 'boolean',
          description: 'Whether to fail the build on lint errors.',
        },
      },
    },
    before: async (
      { failOnLintErrors },
      { workspaceRoot }
    ): Promise<BuilderOutput> => {
      const eslint = new ESLint();
      const results = await eslint.lintFiles([`${workspaceRoot}/**/*.ts`]);

      if (results.length > 0) {
        console.log((await eslint.loadFormatter()).format(results));

        if (failOnLintErrors) {
          throw new Error('ESLint found lint errors.');
        }
      }

      return { success: true };
    },
  }),
];

This code hooks into ng build, but you can hook into other builders too.

HookCommandNode API
buildng buildexecuteBrowserBuilder
serveng serveexecuteDevServerBuilder
build-libng build (in libraries)executeNgPackagrBuilder
i18nng i18nexecuteExtractI18nBuilder
testng testexecuteKarmaBuilder
e2eng e2eexecuteProtractorBuilder

Step 2 - using a hook package

Install the hook package wherever you want to hook into Angular CLI. Then add a angular-cli-hooks.json file to your project and specify the name of the package of hooks

{
  "$schema": "./node_modules/@berglund/angular-cli-hooks/schema.json",
  "hookPackage": "@berglund/builder-hooks"
}

or for multiple hook packages

{
  "$schema": "./node_modules/@berglund/angular-cli-hooks/schema.json",
  "hookPackage": ["@berglund/builder-hooks", "@berglund/more-builder-hooks"]
}

Step 3 - updating angular.json

Update angular.json to use @berglund/angular-cli-hooks over @angular-devkit/build-angular.

{
  "architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser"
    }
  }
}

becomes

{
  "architect": {
    "build": {
      "builder": "@berglund/angular-cli-hooks:browser"
    }
  }
}

And that's it.

Gotchas

  • The JsonSchema for custom configurations is merged with Angular native schemas in the postinstall hook of @berglund/angular-cli-hooks. You have to reinstall to see changes.
  • The before hook will only run before the Angular native builder is invoked the first time.
  • The after hook will run after an Angular builder emits a BuilderOutput. This means the after hook will run for both fresh builds and rebuilds.