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
or if you are using npm
,
npm install @angularclass/hmr --save-dev
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.
}
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"
}
]
}
//
}
}
and for the serve
property,
"serve": {
"configurations": {
//
"hmr": {
"hmr": true,
"browserTarget": "<YOUR_PROJECT_NAME>:build:hmr"
}
//
}
}
then, add node
into the types
array in compilerOptions
in src/tsconfig.app.json
file.
{
//
"compilerOptions": {
//
"types": ["node"]
}
//
}
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
}
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()
})
}
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))
}
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"
}
Success! 👏
We finished configuring HMR for the angular project.
Now try running the app
yarn hmr
or with npm
npm run hmr
Top comments (9)
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.
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.
I made the switch from React to Angular, professionally only ! I prefer React.
Thanks in advance for your help.
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 :)
Hey, i couldnt do that. If you are still having issue, can you share the details?
Great tutorial
thanks! :)
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
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.