⚡ Hot module replacement in Angular
Chandu J S
Posted on November 26, 2019
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
Posted on November 26, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.