NeuroAgent

How to reload an Angular application without page reload

Learn how to use Hot Module Replacement (HMR) in Angular 2+ for fast application reloading without losing state. Step-by-step setup and troubleshooting.

Question

How do I reload an Angular 2+ application without reloading the page?

NeuroAgent

Hot Module Replacement (HMR) in Angular 2+ for Application Reloading Without Page Refresh

In Angular 2+, Hot Module Replacement (HMR) technology is used to reload the application without reloading the page, which allows updating only changed components while preserving the application state and preventing a full page reload.

Table of Contents

What is Hot Module Replacement in Angular?

Hot Module Replacement (HMR) is a technology that allows replacing modules in a running application without requiring a full page reload. In the context of Angular, this means that when code changes:

  • Only changed components are updated
  • Application state is preserved
  • The browser is not fully reloaded
  • Development becomes significantly faster

As explained in the article about HMR on Medium, the main advantage of HMR is instant feedback: developers can see the results of changes in real time without needing to manually refresh the page.


Configuring HMR through angular.json

To enable HMR in an Angular project, you need to configure the angular.json file. Here are the main steps:

  1. Open the angular.json file
  2. Add HMR configuration to the configurations section
json
"configurations": {
  "hmr": {
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.hmr.ts"
      }
    ]
  }
},
"serve": {
  "builder": "@angular-devkit/build-angular:dev-server",
  "configurations": {
    "hmr": {
      "browserTarget": "your-app:build:hmr"
    }
  }
}

As specified in the NGXS documentation, this configuration allows replacing the environment file for HMR mode and configuring the dev-server to work with hot module replacement.


Implementing HMR in main.ts

After configuring angular.json, you need to modify the src/main.ts file to support HMR:

typescript
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode, NgModuleRef } from '@angular/core';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

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

if (environment.hmr) {
  import('@ngxs/hmr-plugin').then(plugin => {
    plugin.hmr(module, bootstrap).catch((err: Error) => console.error(err));
  });
} else {
  bootstrap().catch((err: Error) => console.log(err));
}

This code, as shown in the NGXS example, checks for HMR mode and loads the appropriate plugin. If HMR is not available, the application starts in the standard way.


Installing and configuring HMR packages

HMR in Angular requires special packages. Here are the main options:

Option 1: Using @ngxs/hmr-plugin

bash
npm install @ngxs/hmr-plugin --save-dev

This plugin ensures seamless HMR operation while preserving application state.

Option 2: Using @angularclass/hmr

bash
npm install @angularclass/hmr --save-dev

As described in the PatrickJS/angular-hmr repository, this package provides additional functionality for managing state during hot module replacement.

Option 3: Configuration through webpack

For projects with custom webpack configuration, you can add direct HMR support:

javascript
// webpack.config.js
module.exports = {
  // ... other settings
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ]
};

Troubleshooting HMR issues

Problem: Lazy-loaded routes reload the entire application

As noted in PatrickJS/angular-hmr issue #76, when using lazy-loaded routes, HMR may reload the entire application. Solution:

  1. Ensure that lazy-loaded modules properly handle HMR
  2. Add appropriate handlers to the webpack configuration

Problem: Console errors after HMR

As mentioned in the discussion on DEV Community, in large applications, HMR can cause console errors. Recommendations:

  1. Use module.hot.accept() for proper update handling
  2. Add error handling to dispose functions

Problem: Page still reloads

If HMR is not working and the page continues to reload, check:

  1. Correctness of configuration in angular.json
  2. Presence of the environment.hmr.ts file
  3. Installation of required dependencies

Alternative methods without HMR

1. Using ng serve with the --hmr option

A simple way to enable HMR without complex configuration:

bash
ng serve --hmr

As explained in the article on Medium, this method works for basic scenarios.

2. Using browser developer tools

For debugging and testing, you can use built-in tools:

  • “Network” tab for monitoring requests
  • “Performance” tab for performance analysis
  • Tools for managing application state

3. Reloading specific services

For stateless services, you can implement programmatic reloading:

typescript
constructor(private injector: Injector) {}

reloadService<T>(serviceToken: Type<T>): T {
  const oldInstance = this.injector.get(serviceToken);
  const providers = ReflectiveInjector.resolve([{
    provide: serviceToken,
    useFactory: () => {
      // Create a new service instance
      return this.injector.instantiateDependency(serviceToken);
    }
  }]);
  
  const newInjector = ReflectiveInjector.fromProviders(providers, this.injector);
  return newInjector.get(serviceToken);
}

Sources

  1. Hot Module Replacement (HMR) in Angular: Enhancing Developer Productivity | Medium
  2. NGXS HMR Plugin Documentation
  3. Angular 12 Using HMR (Hot Module Replacement) Example - FreakyJolly
  4. GitHub - PatrickJS/angular-hmr
  5. Hot Module Replacement in Angular - DEV Community
  6. HMR configuration - Angular CLI Issues
  7. Running ng server with --hmr still causes page to reload - Stack Overflow

Conclusion

For reloading an Angular 2+ application without reloading the page, Hot Module Replacement (HMR) technology is the best choice. The main implementation steps are:

  1. Configure angular.json by adding HMR configuration
  2. Modify main.ts to support hot module replacement
  3. Install required packages (@ngxs/hmr-plugin or @angularclass/hmr)
  4. Handle potential issues with lazy-loaded routes and console errors

HMR significantly speeds up development by preserving application state and updating only changed components. For complex projects, it’s recommended to use specialized plugins like @ngxs/hmr-plugin, which provide more reliable state management during hot module replacement.

If HMR is not suitable for your project, you can consider alternative methods such as using ng serve --hmr or programmatic service reloading through Angular’s DI container.