DEV Community

Marcin Wosinek
Marcin Wosinek

Posted on • Edited on

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:

and code generated with ng-cli:

$ npx -p @angular/cli ng new esbuild-ng-cli
Enter fullscreen mode Exit fullscreen mode

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 (...)
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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';
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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

Error: In this configuration Angular requires Zone.js
Enter fullscreen mode Exit fullscreen mode

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 **/
Enter fullscreen mode Exit fullscreen mode

this increases the bundle size to 798.2kb

The working application

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

Links

Summary

You can find the whole codebase in this repository:

GitHub logo marcin-wosinek / esbuild-ng-cli

Proof of a concept for esbuild script for ng cli generated project

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.

Top comments (2)

Collapse
 
aungmyatmoe profile image
Aung Myat Moe

Thank you for this article I am finding like this post since last summer.

Collapse
 
marcinwosinek profile image
Marcin Wosinek

Great, I'm happy to hear it! I just published another article that investigate this angular cli improvement with esbuild:
how-to.dev/how-to-speed-up-angular...