18.0.0 • Published 5 months ago

@angular-builders/custom-esbuild v18.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

Custom ESBuild builders for Angular build facade

npm version npm (tag) npm

Allow customizing ESBuild configuration

Table of Contents

This documentation is for the latest major version only

Previous versions

Prerequisites:

Usage

  1. npm i -D @angular-builders/custom-esbuild
  2. In your angular.json:
    "projects": {
      ...
      "[project]": {
        ...
        "architect": {
          ...
          "[architect-target]": {
            "builder": "@angular-builders/custom-esbuild:[application|dev-server]",
            "options": {
              ...
            }
    Where:
  3. If [architect-target] is not one of the predefined targets (like build, serve, test etc.) then run it like this:
    ng run [project]:[architect-target]
    If it is one of the predefined targets, you can run it with ng [architect-target]

For Example

  • angular.json:
    "projects": {
      ...
      "example-app": {
        ...
        "architect": {
          ...
          "build": {
            "builder": "@angular-builders/custom-esbuild:browser",
            "options": {
              ...
            }
  • Run the build: ng build

Builders

Custom ESBuild application

The @angular-builders/custom-esbuild:application builder is an extension of the @angular-devkit/build-angular:application builder, allowing the specification of additional properties on top of the existing ones. The custom builder runs the original builder at the end, incorporating extra parameters specified in the extended configuration. It will also perform index.html transformations if specified.

Builder options:

  • All the @angular-devkit/build-angular:application options
  • plugins
  • indexHtmlTransformer: see below

Example

angular.json:

"architect": {
  ...
  "build": {
    "builder": "@angular-builders/custom-esbuild:application",
    "options": {
      "plugins": ["./esbuild/plugin-1.js", "./esbuild/plugin-2.js"],
      "indexHtmlTransformer": "./esbuild/index-html-transformer.js",
      "outputPath": "dist/my-cool-client",
      "index": "src/index.html",
      "browser": "src/main.ts",
      "polyfills": ["zone.js"],
      "tsConfig": "src/tsconfig.app.json"
    }

In the above example, we specify the list of plugins that should implement the ESBuild plugin schema. These plugins are custom user plugins and are added to the original ESBuild Angular configuration. Additionally, the indexHtmlTransformer property is used to specify the path to the file that exports the function used to modify the index.html.

Custom ESBuild dev-server

The @angular-builders/custom-esbuild:dev-server is an enhanced version of the @angular-devkit/build-angular:dev-server builder that allows the specification of middlewares (Vite's Connect functions). It also obtains plugins and indexHtmlTransformer from the :application configuration to run the Vite server with all the necessary configuration applied.

Example

angular.json:

"architect": {
  ...
  "build": {
    "builder": "@angular-builders/custom-esbuild:application",
    "options": {
      "plugins": ["./esbuild/plugin-1.js"]
      ...
    }
  },
  "serve": {
    "builder": "@angular-builders/custom-esbuild:dev-server",
    "options": {
      "middlewares": ["./esbuild/my-middleware.js"],
      "buildTarget": "my-project:build"
    }
  }

Index Transform

Since Angular 8, index.html is not generated as part of the build. If you want to modify your index.html, you should use the indexHtmlTransformer option. indexHtmlTransformer is a path (relative to the workspace root) to a .js or .ts file that exports a transformation function for index.html. If indexHtmlTransformer is written in TypeScript, the application's tsConfig file will be used by tsnode for its execution:

(options: TargetOptions, indexHtmlContent: string) => string | Promise<string>;

or, in other words, the function receives target options and original index.html content (generated by Angular CLI) and returns a new content as string or Promise<string>.
TargetOptions follows target definition from this schema and looks like this:

export interface Target {
  configuration?: string;
  project: string;
  target: string;
}

It is useful when you want to transform your index.html according to the build options.

Example

angular.json:

"architect": {
  ...
  "build": {
    "builder": "@angular-builders/custom-esbuild:application",
    "options": {
      "indexHtmlTransformer": "./esbuild/index-html-transformer.js"
      ...
    }

index-html-transformer.js:

module.exports = (targetOptions, indexHtml) => {
  const i = indexHtml.indexOf('</body>');
  const config = `<p>Configuration: ${targetOptions.configuration}</p>`;
  return `${indexHtml.slice(0, i)}
            ${config}
            ${indexHtml.slice(i)}`;
};

Alternatively, using TypeScript:

import { Target } from '@angular-devkit/architect/src/input-schema';
import { json } from '@angular-devkit/core';

type TargetOptions = json.JsonObject & Target;

export default (targetOptions: TargetOptions, indexHtml: string) => {
  const i = indexHtml.indexOf('</body>');
  const config = `<p>Configuration: ${targetOptions.configuration}</p>`;
  return `${indexHtml.slice(0, i)}
            ${config}
            ${indexHtml.slice(i)}`;
};

In the example we add a paragraph with build configuration to your index.html. It is a very simple example without any asynchronous code but you can also return a Promise from this function.

ES Modules (ESM) Support

Custom ESBuild builder fully supports ESM.

  • If your app has "type": "module" both plugin.js and index-html-transformer.js will be treated as ES modules, unless you change their file extension to .cjs. In that case they'll be treated as CommonJS Modules. Example.
  • For "type": "commonjs" (or unspecified type) both plugin.js and index-html-transformer.js will be treated as CommonJS modules unless you change their file extension to .mjs. In that case they'll be treated as ES Modules. Example.
  • If you want to use TS config in ESM app, you must set the loader to ts-node/esm when running ng build. Also, in that case tsconfig.json for ts-node no longer defaults to tsConfig from the application target - you have to specify it manually via environment variable. Example.
    Note that tsconfig paths are not supported in TS configs within ESM apps. That is because tsconfig-paths do not support ESM.
18.0.1-beta.0

5 months ago

18.0.0-beta.3

7 months ago

18.0.0-beta.2

7 months ago

17.1.3-beta.2

7 months ago

18.0.0

6 months ago

17.1.3-beta.1

9 months ago

17.1.3-beta.0

9 months ago

17.1.2

9 months ago

17.1.2-beta.2

9 months ago

17.1.2-beta.3

9 months ago

17.1.2-beta.1

9 months ago

17.1.2-beta.0

9 months ago

17.1.1-beta.1

10 months ago

17.1.1

10 months ago

17.1.1-beta.0

10 months ago

17.1.0

10 months ago

17.1.0-beta.3

11 months ago

17.1.0-beta.2

11 months ago

17.1.0-beta.1

11 months ago

17.1.0-beta.0

11 months ago