HMR & Ionic 4 — A better live-reload

Jordan Benge
3 min readApr 25, 2019

--

I originally was annoyed with how Ionic 4 handles live-reloading. I always felt like the reloads would take forever, even for a small and simple change. So I decided to do some Googling and learned of Hot Module Reload (HMR) which only recompiles the files that you have recently changed. This results in nicer and faster development experiences.

Getting Started

Start off by installing the HMR dependency: npm install — save-dev @angularclass/hmr

Next, create a new environment file called environment.hmr.ts you can add in any extra details you have in your other environment.tsfiles but this is at the very least what it should look like:

export const environment = {
production: false,
hmr: true
};

Next, in both environment.prod.ts and environment.ts files, add hmr:false opposite of the environment.hmr.ts file.

Next, in your angular.json file, you’ll need to alter it so that it looks something like the following:

"build": {
"configurations": {
...
"hmr": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.hmr.ts"
}
]
}
}
},
...
"serve": {
"configurations": {
...
"hmr": {
"hmr": true,
"browserTarget": "app:build:hmr"
}
}
}

Adding in the appropriate types:

In your tsconfig.app.json file make sure to add the node type into the types array.

{
...
"compilerOptions": {
...
"types": ["node"]
},
}

And install node types it if you haven’t already:npm install @types/node

Configuring hmr.ts

We’ll now need to create a file called hmr.ts which we’ll pull under src it should be the following:

import { ApplicationRef, NgModuleRef } 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();
});
};

Changing main.ts

One of the last steps to get this to work is to alter our main.ts file to use HMR

import { hmrBootstrap } from './hmr';
...
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));
}

And the final step is to alter our package.json file scripts to handle the new setting. I changed the default start script, but you can create a new one if you so choose.

"scripts": {
"start": "ng serve --configuration hmr",
...
},

And that’s it! This article was only made possible because of the awesome writeup and documentation of how HMR works by the Angular CLI team. It’s an underknown setting that really helps development in Ionic 4. Check out some of my other articles for more useful solutions within the Ionic framework.

Questions?

You can find me on:
- GitHub: https://github.com/bengejd/
- Medium: https://medium.com/@JordanBenge

Who am I? My name is Jordan Benge, I am a Software Developer who loves helping others and contributing to Open-Source. I’ve been working in the Ionic Framework since Ionic 1, and have tried to keep up to date on the latest and greatest when it comes to Hybrid Mobile App Development.

If you enjoyed this story, please click the 👏 button and share to help others find it! Feel free to leave a comment below if you need any help.

--

--

Jordan Benge
Jordan Benge

Written by Jordan Benge

My name is Jordan Benge, I’m a freelance developer, who sometimes likes to write helpful articles on Medium for people who want to do things but don’t know how.

Responses (2)