Search code examples
angulartypescriptwebpack-hmr

Hmr issues after update Angular


I'm working with some legacy code, and I decided to update it to Angular 9. I've resolved most of the other issues, but i'm stuck on this error throw by some HMR code.

 src/main.ts:16:7 - error TS2591: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.

16   if (module['hot']) {
         ~~~~~~
src/main.ts:17:18 - error TS2591: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.

17     hmrBootstrap(module, bootstrap);

It says that module type cannot be found. The other answers I've found say delete all your nodule_modules and reinstall, add [nodes] to types, or change import of { environments } in tsconfig, but all of these seem correct, so I'm not entirely sure why it can't find module. This code was working in Angular 5.2 and must have gotten messed up along the way.

I've scanned through some files and this is what I've found

  • main.ts
import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";

import { AppModule } from "./app/app.module";
import { environment } from "./environments/environment";

import { hmrBootstrap } from "./hmr";

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

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

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();
}

  • hmr.ts
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();
  });
};
  • tsconfig.app.json
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "types": [
      "nodes"
    ]
  },
  "files": [
    "main.ts",
    "polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

I've been on this issue for a while so any help would be gratly appreciated. Thanks!


Solution

  • You have a typo in your tsconfig.app.json file. The correct type to add is node and not nodes:

    {
      ...
      "types": [
        "node"
      ]
      ...