Angular CLI:配置webpack热模块替换hmr(Hot Module Replacement)

时间:2021-11-08 17:48:20

热模块替换(Hot Module Replacement)是Webpack的特性,它可以让我们在调试时不需要重新构建就可以更新代码到正在运行的应用。

Angular CLI需要做一些设置就可以使用webpack的热模块替换功能。

添加依赖

hrm依赖于@angularclass/hmr,安装@angularclass/hmr到dev-dependency

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

添加HMR环境

新建src/environments/environment.hmr.ts文件,内容如下:

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

修改src/environments/environment.prod.ts,添加hmr:false

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

修改src/environments/environment.ts,添加hmr:false

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

修改.angular-cli.json,添加hmr环境

"environments": {
  "dev": "environments/environment.ts",
  "hmr": "environments/environment.hmr.ts",
  "prod": "environments/environment.prod.ts"
},

使用hmr

新建src/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();
  });
};

在src/main.ts新增对hmr环境的检查,对于hmr环境使用hmr.ts的hmrBootstrap启动:

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

运行启动

ng server启动

ng serve --hmr -e=hmr

npm脚本启动

在package.json新增脚本

"scripts": {
  ...
  "hmr": "ng serve --hmr -e=hmr"
}

执行

npm run hmr