angular-cli如何启用HMR

先决条件

angular cli 至少 1.0.0-beta.22 以上版本

创建项目

使用Angular CLI创建一个空项目。

ng new demo
cd demo

添加HMR环境配置文件

HMR需要一定代码嵌入,而这些模块我们希望只在开发过程中使用,所以这里创建一个环境配置文件,用于区分我们什么时候需要引入 hmr 模块,而不会影响我们生产环境。

首先,创建 src/environments/environment.hmr.ts 文件,内容为:

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

这里相比较默认两个环境,增加了 hmr: true 变量。那么,另外两个,也一并设置相应 hmr 变量,来确保什么情况下才允许开启 HMR。

environment.prod.ts 生产环境肯定不会开启它:

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

environment.ts 默认环境,如果有必要也可以设置为 true,为了后面更好的演示,这里我设置 false

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

新环境配置还需要更新 angular-cli.jsonenvironments 节点,以确保angular cli 能认识:

"environments": {
        "source": "environments/environment.ts",
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts",
        // 新增的节点
        "hmr": "environments/environment.hmr.ts"
      }

到此,与配置相关已经完成,你可以尝试使用 ng serve --hmr -e=hmr 来启用HMR。而且和之前相比会有这样一段提醒:

NOTICE Hot Module Replacement (HMR) is enabled for the dev server.The project will still live reload when HMR is enabled,but to take advantage of HMR additional application code is required(not included in an Angular CLI project by default).See https://webpack.github.io/docs/hot-module-replacement.htmlfor information on working with HMR for Webpack.

添加angular-hmr模块依赖与配置

正如提醒信息中说的,Angular CLI默认并不提供HMR所需要的额外应用代码。但Angular已经有了一个现成HMR模块即【Angular 2 Hot Module Replacement】,安装它:

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>) => {
    let ngModule: NgModuleRef;
    module.hot.accept();
    bootstrap().then(mod => {
        ngModule = mod;
    });
    module.hot.dispose(() => {
        let appRef: ApplicationRef = ngModule.injector.get(ApplicationRef);
        let elements = appRef.components.map(c => c.location.nativeElement);
        let makeVisible = createNewHosts(elements);
        ngModule.destroy();
        makeVisible();
    });
};

最后,修改 src/main.ts 内容:

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

import { hmrBootstrap } from './hmr';

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

const bootstrap = () => {
  return platformBrowserDynamic().bootstrapModule(AppModule);
}

if (environment.hmr) {
  if (module['hot']) {
    hmrBootstrap(module, bootstrap);
  } else {
    // 未加上 --hmr 时,控制台会有错误提醒
    console.error('HMR没有启用,确保 ng server 命令加上 --hmr 标记');
  }
} else {
  bootstrap();
}

运行

现在,我们可以使用以下命令来启动HMR:

ng serve --hmr -e=hmr

你可能感兴趣的:(angular-cli如何启用HMR)