让@angular/cli项目支持Hot Module Replacement(HMR)

什么是HMR?

噢,你自己看看这里的官方文档就好了,不解释。

@angluar/cli 默认没有很好地支持HMR,我们需要手动做一些事情。

请跟我一步一步来玩。

第一步:修改环境配置文件

为了后续操作能顺利进行,首先需要修改默认生成的两份环境配置文件:src/environments/environment.ts 和 src/environments/environment.prod.ts

在这两份配置文件里面都增加一个配置项hmr:false,变成这样:

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

第二步:新建一份hmr配置文件

创建一份全新的环境配置文件:src/environments/environment.hmr.ts

environment.hmr.ts 里面的内容如下:

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

修改.angular-cli.json,加一行配置,变成这样:

"environmentSource": "environments/environment.ts",
"environments": {
      ...
      "hmr": "environments/environment.hmr.ts",
}

修改package.json,加一行脚本:

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

第三步:安装第三方支持模块同时写一些代码

npm install --save-dev @angularclass/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(currentModule => ngModule = currentModule);
  module.hot.dispose(() => {
      const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef);
      const elements = appRef.components.map(c => c.location.nativeElement);
      const removeOldHosts = createNewHosts(elements);
      ngModule.destroy();
      removeOldHosts();
  });
};

代码很简单,相信你能看懂,不解释了。

写一行代码很简单,解释一行代码可能需要一千行注释,故:一码胜千言。

修改默认生成的src/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('Ammm.. HMR is not enabled for webpack');
    }
} else {
    bootstrap();
}

第四步:启动项目

npm run hmr

然后你会看到这样的警告,无视就好了:

0_1526265442479_22222.png

注意点

  • HMR的好处是:开发的时候不需要每次都整体刷新浏览器,只替换被修改过的模块
  • 不要把HMR在生产环境里面,因为你不能每次改了代码都去刷所有客户的浏览器
  • HMR启动的方式不是ng serve,而是npm run hmr,请特别注意一下。

cli v6.x已经内置了HMR支持

特别注意:最新的@angular/cli 6.x 版本已经内置了 HMR 支持,只要执行以下命令即可(上面的所有步骤都不需要了,所以赶紧升级到V6.0吧!):

ng serve --hmr

OpenWMS这个项目的前端已经升级到V6.0.0,有需要参考一下吧:https://gitee.com/mumu-osc/OpenWMS-Frontend/invite_link?invite=55233fd7f770d4d27211249dd70ed32a76b37f35b73c0d4cd1951d64d3940eac1a09551ecc8036f6


本文由 @业余小编 意译改写,英文版原文在这里:https://medium.com/wizardnet972/hot-module-replacement-with-angular-cli-5fc7a3ae4a9c

有点跟不上节奏了~ 😅

厉害 试一试

登录后回复

与 Angular开发者 的连接断开,我们正在尝试重连,请耐心等待