Categories
Uncategorized

How To Enable Hot Module Replacement (HMR) in Angular 12

Share

An Angular project is normally recompiled multiple times to rebuild and paint the views, loading modules, CSS, etc., even with minor changes saved. Development builds require much more time than production builds, since updating browsers to reflect minor changes can take quite a bit of time. So, Angular released a solution to this issue.

What is Hot Module Replacement (HMR)?

Hot Module Replacement (HMR) is a key webpack feature in Angular, but it is not enabled by default. With the HMR, you can exchange, add, or remove modules while an application is running without a full reload. This allows developers to only update what has changed.

How to Create a New Angular Application

Using the following command, you can create an Angular Project

$ ng new angular-hmr-app
# ? Would you like to add Angular routing? Yes
# ? Which stylesheet format would you like to use? CSS

Project directory

$ cd angular-hmr-app

Open an app in VS Code

$ code

Our Angular project is now ready to implement the HMR feature test.

Implementation of Hot Module Replacement (HMR)

Two environment files are used to create an Angular project: one for development and one for production. We’re going to create another HMR environment file here.

  • Setup Project Environments

Make a new file ‘~src/environments/environment.hmr.ts’ and update it with the following:

export const environment = {

   production: false,

   hmr: true

};

You should update the ‘~src/environments/environment.ts’ file and add hmr: false

export const environment = {

  production: false,

  hmr: false

};

You should update the ‘~src/environments/environment.prod.ts’ file  and add hmr: false

export const environment = {

  production: true,

  hmr: false

};

  • Update the angular.json file

Make sure to update the angular.json file with the NG CLI configurations. In order to enable HMR during the build and serve processes, configurations must be added.

Change the “configurations” properties for “build” and “serve” in the angular.json file by adding “hmr”

“build”: {

    “configurations”: {

      …

      “hmr”: {

        “fileReplacements”: [

          {

            “replace”: “src/environments/environment.ts”,

            “with”: “src/environments/environment.hmr.ts”

          }

        ]

      }

    }

  },

  …

  “serve”: {

    “configurations”: {

      …

      “hmr”: {

        “hmr”: true,

        “browserTarget”: “angular-hmr-app:build:hmr”

      }

    }

  }

Note: Replace “angular-hmr-app” with the name of your application.

  • Update tsconfig.app.json

Add types to the file ‘~src/tsconfig.app.json’

{

  …

  “compilerOptions”: {

    …

    “types”: [“node”]

  },

}

  • Set up @angularclass/hmr

Our project will not work with HMR unless we integrate its dependencies. You can install the @angularclass/hmr module by running the following command.

$ npm install –save-dev @angularclass/hmr

Now, create the ‘~src/hmr.ts’ file and update the code.

// src/hmr.ts

import { NgModuleRef, ApplicationRef } from ‘@angular/core’;

import { createNewHosts } from ‘@angularclass/hmr’;

export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => {

  let ngModule: NgModuleRef<any>;

  module.hot.accept();

  bootstrap().then(mod => ngModule = mod);

  module.hot.dispose(() => {

    const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef);

    const elements = appRef.components.map(c => c.location.nativeElement);

    const makeVisible = createNewHosts(elements);

    ngModule.destroy();

    makeVisible();

  });

};

  • Update main.ts file

In order to change the bootstrap process, update the ‘~src/main.ts’ file with the hmr.ts we created in the previous step.

// main.ts

import { enableProdMode } from ‘@angular/core’;

import { platformBrowserDynamic } from ‘@angular/platform-browser-dynamic’;

import { AppModule } from ‘./app/app.module’;

import { environment } from ‘./environments/environment’;

import { hmrBootstrap } from ‘./hmr’;

if (environment.production) {

  enableProdMode();

}

const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule);

if (environment.hmr) {

  if (module[ ‘hot’ ]) {

    hmrBootstrap(module, bootstrap);

  } else {

    console.error(‘HMR is not enabled for webpack-dev-server!’);

    console.log(‘Are you using the –hmr flag for ng serve?’);

  }

} else {

  bootstrap().catch(err => console.log(err));

}

In the development phase, we can save time by executing the Hot Module Replacement technique and this important feature provided by Webpack. This article is helpful for compatibility with Angular 4 to the latest version, and the versions are Angular 7, Angular 8, Angular 9, Angular 10, Angular 11, and Angular 12.


Share