DEV Community

Cover image for ⚡ Hot module replacement in Angular
Chandu J S
Chandu J S

Posted on • Updated on • Originally published at chandujs.dev

⚡ Hot module replacement in Angular

When working with angular projects, live reloading is a must. But whenever you change something in the code, the whole page will reload. Hot Module Replacement (HMR) is a feature in webpack that allows for modules to be replaced without a full browser reload. Changes will get updated instantly. This feature allows you to maintain much of the application state usually lost when reloading the page. But this is not enabled by default in angular. We need to do some adjustments to your project to get this run.

So, let's start...

1. Install Dependency

yarn add @angularclass/hmr --dev
Enter fullscreen mode Exit fullscreen mode

or if you are using npm,

npm install @angularclass/hmr --save-dev
Enter fullscreen mode Exit fullscreen mode

2. Add New Environment

Add a new environment file called environment.hmr.ts inside your src/environments folder with following code.

export const environment = {
  production: false,
  hmr: true,
  // you can add your existing development configs from `environment.ts` file here.
}
Enter fullscreen mode Exit fullscreen mode

Now, we have a new environment file. We need to update build & serve properties in the angular.json file with the following configurations.

for the build property,

"build": {
  "configurations": {
    //
    "hmr": {
      "fileReplacements": [
        {
          "replace": "src/environments/environment.ts",
          "with": "src/environments/environment.hmr.ts"
        }
      ]
    }
    //
  }
}
Enter fullscreen mode Exit fullscreen mode

and for the serve property,

"serve": {
  "configurations": {
    //
    "hmr": {
      "hmr": true,
      "browserTarget": "<YOUR_PROJECT_NAME>:build:hmr"
    }
    //
  }
}
Enter fullscreen mode Exit fullscreen mode

then, add node into the types array in compilerOptions in src/tsconfig.app.json file.

{
  //
  "compilerOptions": {
    //
    "types": ["node"]
  }
  //
}
Enter fullscreen mode Exit fullscreen mode

3. Update Existing Environments

Next, we need to add an hmr property with value false in all other environment files (except environment.hmr.ts).

export const environment = {
  //
  hmr: false
}
Enter fullscreen mode Exit fullscreen mode

4. Configure Your Application

Create a new file named hmr.ts inside src folder with following content.

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

then, we need to modify the main.ts file inside src folder to use HMR feature.

import { enableProdMode } from '@angular/core'
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
import { environment } from './environments/environment'
import { hmrBootstrap } from './hmr'
import { RootModule } from './app/root/root.module'

if (environment.production) {
  enableProdMode()
}

const bootstrap = () => platformBrowserDynamic().bootstrapModule(RootModule)

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

5. Add NPM Script

Add an hmr property in scripts object in the package.json file to make running app easier.

"scripts": {
  //
  "hmr": "ng serve --configuration hmr"
}
Enter fullscreen mode Exit fullscreen mode

Success! 👏

We finished configuring HMR for the angular project.
Now try running the app

yarn hmr
Enter fullscreen mode Exit fullscreen mode

or with npm

npm run hmr
Enter fullscreen mode Exit fullscreen mode

Top comments (9)

Collapse
 
nikrou77 profile image
Nicolas

I follow your tutorial but unfortunatly it does not work. Have you a working demo repository ?
The minimal working example can for example contains a form a text field. I put some content in a text field. I change my code and add another text field. The second text field must appear and the other text field must keep its content. Can it works ?
Best regards.

Collapse
 
ctrleffive profile image
Chandu J S

I was using it on my own website. Recently I ported my website to React. I didn't used HMR for angular after that. I'll try to set up a demo and let you know.

Collapse
 
nikrou77 profile image
Nicolas • Edited

I made the switch from React to Angular, professionally only ! I prefer React.
Thanks in advance for your help.

Collapse
 
kazandzhiro profile image
Ivan Kazandzhiev

Hey, did you manage to set up a working demo? I am able to set up but the changes are not reflected (no listener for webpackHotUpdate)
Thank you for listing out the steps to setup :)

Thread Thread
 
ctrleffive profile image
Chandu J S

Hey, i couldnt do that. If you are still having issue, can you share the details?

Collapse
 
ruslangonzalez profile image
Ruslan Gonzalez

Great tutorial

Collapse
 
ctrleffive profile image
Chandu J S

thanks! :)

Collapse
 
dpapini profile image
dpapini

hi good work, but i've a problem.

when i run my projext i receive the follow error:

No NgModule metadata found for 'AppModule'.

can someone help me?

thank you

Collapse
 
ctrleffive profile image
Chandu J S

Hey,
Try this solution, stackoverflow.com/questions/396851...
If that doesn't help you, can you reproduce your issue in a stackblitz env? I can take a look.