How to dev

How to dev

How to build angular cli application with esbuild

Are you curious if it's possible to build ng-cli generate application with esbuild - js bundling tool that is gaining popularity because of it very fast speed? It is, at least with a simplify proof-of-a-concept app; and with a bit of tweaking to the code.

Starting point

My starting point is esbuild command shown & discussed in: how-to.dev/how-to-build-minimal-angular-12-..

and code generated with ng-cli:

$ npx -p @angular/cli ng new esbuild-ng-cli

asciicast

probably due to some recent package updates, I needed to tweak dependencies before the installation passed.

esbuild install & configuration

We need few more steps to build with esbuild. First, installing esbuild as dependency:

$ npm install esbuild --save-dev

added 1 package (...)

Then we need build script. As we are not yet doing complete migration to esbuild, I'll leave npm run build as it was created - on webpack, and add dedicated esbuild script:

"esbuild": "esbuild src/main.ts --bundle --outfile=dist/main.js --loader:.html=text --minify"

There are few things included in this command:

  • src/main.ts - is the script entry point - from there esbuild start finding all dependecies
  • --bundle - tell esbuild to bundle all files into one bundle file
  • --outfile=dist/main.js - the target of our build
  • --loader:.html=text - makes HTML files interpreted as strings. It's similar to raw-loader in webpack
  • --minify - minimize our code. It's not as effective as angular main configuration, but it's much better than leaving code unoptimized.

The necessary tweaks to the code, is to replace src/app/app.component.ts with:

import { Component } from '@angular/core';

import template from './app.component.html';

@Component({
  selector: 'app-root',
  template,
  // styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'esbuild-ng-cli';
}

templateUrl is replace by explicit template load, and css import I dropped to simplify the proof-of-a-concept application.

For the TS complication to accept the HTML import, we need to add index.d.ts with:

declare module "*.html" {
  const content: string;
  export default content;
}

With those changes in place, we can already see the build passing:

$ npm run esbuild                   

> esbuild-ng-cli@0.0.0 esbuild
> esbuild src/main.ts --bundle --outfile=dist/main.js --loader:.html=text --minify


  dist/main.js  761.1kb

⚡ Done in 124ms

The speed is impressive - less than 1 second. Unfortunately the bundle size is much bigger than one produce by native setup - 170.87kb, but build time almost 13s.

Note that the esbuild specific changes brake the standard webpack build - we would need some tweaks to have those two coexists without troubles.

HTML file

For quick testing the app, we will use quick & dirty html; inspired by the webpack output. The ./index.html:

<!DOCTYPE html><html lang="en"><head>
  <meta charset="utf-8">
  <title>EsbuildNgCli</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
<body>
  <app-root></app-root>
<script src="dist/main.js"></script>
</body></html>

if we visit our page now, it will fail with:

Error: In this configuration Angular requires Zone.js

in the browser console. We can address it by adding one line to ./src/main.ts:

import 'zone.js';

import { enableProdMode } from '@angular/core';
/** the rest of the file **/

this increases the bundle size to 798.2kb

The working application

The final app works the same as with the original build: Alt Text

You can see the working example at: marcin-wosinek.github.io/esbuild-ng-cli

Summary

You can find the whole codebase in this repository: github.com/marcin-wosinek/esbuild-ng-cli

This topic could be expanded in multiple ways

  • more real work application
  • adding css support
  • setting up dev server with esbuild
  • real esbuild & webpack coexistence - maybe it makes sense to have quick dev & heavily optimized production build
  • schematics for generating esbuild-friendly code immediately with ng-cli
  • some other code generators set up with esbuild

let me know in the comments if those or any other extension are interesting for you.

Interested in reading more such articles from Marcin Wosinek?

Support the author by donating an amount of your choice.

 
Share this
Proudly part of