详解Angular5/Angular6项目如何添加热更新(HMR)功能

下面是详解Angular5/Angular6项目如何添加热更新(HMR)功能的完整攻略。

需要的前置条件

  • Angular CLI
  • Angular5或Angular6项目

步骤一:安装相关依赖

首先我们需要安装@angularclass/hmrwebpack-bundle-analyzer插件。运行下面的命令进行安装:

npm install --save-dev @angularclass/hmr webpack-bundle-analyzer

步骤二:修改app.module.ts

app.module.ts中,我们需要添加一些代码来实现HMR。具体代码如下:

import { NgModule, ApplicationRef, NgModuleRef } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { createNewHosts, removeNgStyles } from '@angularclass/hmr';

@NgModule({
  imports: [BrowserModule],
})
export class AppModule {
  constructor(private appRef: ApplicationRef, private moduleRef: NgModuleRef<any>) {}

  hmrOnInit(store: any) {
    if (!store || !store.state) {
      return;
    }
    console.log('HMR store', JSON.stringify(store, null, 2));
    if ('restoreInputValues' in store) {
      store.restoreInputValues();
    }
    const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
    this.moduleRef.destroy();
    this.appRef.detachView(cmpLocation);
    // Create new host elements, rebuild styles
    const elements = createNewHosts(cmpLocation);
    // Reload state if it exists
    if ('disposeOldHosts' in this.moduleRef) {
      (<any>this.moduleRef).disposeOldHosts();
    }
    this.moduleRef = null;
    // Bootstrap the app
    setTimeout(() => {
      this.moduleRef = this.compiler.compileModuleSync(AppModule);
      const ngModule = this.moduleRef.create(this.injector, elements);
      this.appRef.attachView(ngModule.hostView);
    }, 0);
    // Restore input values
    if ('restoreInputValues' in store) {
      setTimeout(store.restoreInputValues, 0);
    }
    // Destroy old subscription if needed
    if (!this.subscription) {
      this.subscription = this.router.events.subscribe(event => {
        if (event instanceof NavigationEnd) {
          // Restore scroll position
          const restoredValues = store && store.state && store.state[this.router.url];
          if (restoredValues) {
            setTimeout(() => this.viewportScroller.scrollToPosition(restoredValues), 0);
          }
        }
      });
    }
  }

  hmrOnDestroy(store: any) {
    if (this.moduleRef) {
      this.appRef.detachView(this.appRef.components.map(cmp => cmp.location.nativeElement));
      this.moduleRef.destroy();
    }
    this.moduleRef = null;
    this.subscription.unsubscribe();
    this.subscription = null;
  }

  hmrAfterDestroy(store: any) {
    // Display new elements
    store.disposeOldHosts = createNewHosts(this.appRef.components.map(cmp => cmp.location.nativeElement));
    // Save scroll position
    store.state = {};
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        store.state[this.router.url] = this.viewportScroller.getScrollPosition();
      }
    });
  }
}

步骤三:修改webpack配置

webpack.dev.js文件中,找到module.exports对象中的entry选项,并添加以下代码:

entry: {
  polyfills: [...]
  vendor: [...],
  main: [
    './src/main.ts' // <-- Add this line
  ]
},

接下来,在同一个文件中找到module.exports对象中的output选项,并添加以下代码:

output: {
  path: helpers.root('dist'),
  filename: '[name].bundle.js',
  sourceMapFilename: '[name].map',
  chunkFilename: '[id].chunk.js',
  publicPath: '/',
  libraryTarget: 'var'
},

然后,在同一个文件中找到module.exports对象中的plugins选项,并添加以下代码:

new AngularCompilerPlugin({
  // ...
  "define": {
    "HMR": true
  },
  // ...
})

最后,在同一个文件中的末尾添加以下代码:

module.exports = function(env) {
  var hmrEnabled = env && env.HMR === true;
  // ...
  if (hmrEnabled) {
    config.plugins.push(new webpack.HotModuleReplacementPlugin());
    Object.keys(config.entry).forEach(function (entryName) {
      config.entry[entryName] = config.entry[entryName].concat('webpack-hot-middleware/client');
    });
  }
  // ...
  return config;
};

步骤四:启动HMR

运行以下命令启动HMR:

ng serve --hmr

运行成功后,修改代码并保存即可看到热更新的效果。

示例一:开启HMR并监测打包后的大小

运行以下命令启动HMR并监测打包后的大小:

ng serve --hmr --stats-json

启动成功后,可以在localhost:4200看到应用,并且在stats.json文件中得到打包后的大小。

示例二:在正在运行的应用程序中手动启用HMR

可以手动启用HMR来避免在重启应用程序之前等待HMR启用的时间。

添加以下代码:

import { ApplicationRef, NgModuleRef } from '@angular/core';
import { getNgZone } from '@angularclass/hmr';
declare const System: any;

export const hmrBootstrap = (
  module: any,
  bootstrap: () => Promise<NgModuleRef<any>>
) => {
  let ngZone: NgZone;
  module.hot.accept();
  bootstrap().then((ngModuleRef: NgModuleRef<any>) => {
    ngZone = getNgZone(ngModuleRef.injector);
    module.hot.dispose(() => {
      const appRef: ApplicationRef = ngModuleRef.injector.get(ApplicationRef);
      const elements = appRef.components.map(c => c.location.nativeElement);
      const makeVisible = createNewHosts(elements);
      ngModuleRef.destroy();
      ngZone.run(() => {
        const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule);
        hmrBootstrap(module, bootstrap);
      });
    });
  });
};

然后在main.ts中添加以下代码:

if (module['hot']) {
  hmrBootstrap(module, bootstrap);
} else {
  bootstrap();
}

运行应用后,在需要启用HMR的地方输入以下代码:

declare const require: any;
const hotFix = require('webpack/hot/overlay');
hotFix.handle(module);

手动启用HMR后,修改代码并保存即可看到热更新的效果。

综上所述,这就是“详解Angular5/Angular6项目如何添加热更新(HMR)功能”的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Angular5/Angular6项目如何添加热更新(HMR)功能 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • Vue.js3.2的vnode部分优化升级使用示例详解

    Vue.js3.2的vnode部分优化升级使用示例详解 简介 在Vue.js 3.2版本中,vnode相关的部分进行了优化升级。利用这些更新,可以优化Vue.js的性能表现。本文将详细讲解Vue.js的vnode优化升级,并提供几个使用示例。 vnode优化升级 在Vue.js 3.2版本中,vnode的处理更快。它现在可以将创建新vnode所需的时间降低了…

    node js 2023年6月8日
    00
  • 使用Node.js给图片加水印的方法

    我们来详细讲解一下使用Node.js给图片加水印的方法。 环境准备 首先要确保已经安装了Node.js环境,可以在命令行界面输入以下命令检查: node -v 如果有对应的版本号输出,则说明Node.js已经正确安装成功。 安装依赖库 图片处理需要用到ImageMagick库,可以通过以下命令进行安装: npm install imagemagick 安装完…

    node js 2023年6月8日
    00
  • Node.js中的模块化,npm包管理器详解

    Node.js中的模块化 Node.js中模块化的核心思想是将代码段封装起来,使得模块与模块之间彼此独立,提高了代码的可重用性,并且使得代码更加易维护。Node.js的模块化分为两类:核心模块和文件模块。 核心模块 Node.js自带了一些核心模块,例如http、fs、path等,这些模块可以直接在代码中使用,无需安装任何第三方模块,也无需指定路径。 以下是…

    node js 2023年6月8日
    00
  • node.js的http.createServer过程深入解析

    现在我将详细讲解一下“node.js的http.createServer过程深入解析”的完整攻略,希望对您有所帮助。 http.createServer的作用 在深入了解http.createServer的过程之前,我们需要先了解它的作用。http.createServer是node.js中的一个方法,用于创建一个http服务器。我们可以通过该服务器监听客户…

    node js 2023年6月8日
    00
  • Vue的elementUI实现自定义主题方法

    Vue的elementUI实现自定义主题方法 ElementUI是Vue的组件库,提供了丰富多彩的UI组件供我们进行开发和设计。自带主题的独特性可以满足日常开发和设计所需要的层次。 但是,在实际项目开发中,可能会面临着需要定制特定主题的情况,这时候,就需要通过自定义样式来解决了。 Vue的elementUI实现自定义主题方法,基本步骤如下: 1)安装依赖: …

    node js 2023年6月9日
    00
  • 一步一步asp.net ajax类别Tree生成

    一步一步asp.net ajax类别Tree生成攻略: 安装必要的 Nuget 包 在 Visual Studio 中打开项目,右键单击项目并选择“管理 Nuget 程序包”。 在“浏览”选项卡下搜索“Microsoft.AspNet.WebApi.Core”和“Microsoft.AspNet.WebApi.Owin”,然后点击“安装”。这些程序包是必要的…

    node js 2023年6月8日
    00
  • 使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目

    关于“使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目”的完整攻略,我们可以分为以下几个部分来进行讲解。 I. 环境准备 首先,需要安装Node.js,并且建议安装最新版本。在安装完成之后,我们可以打开终端(Command Prompt或者Terminal),输入以下命令: npm install -g grunt-cli 这个命令…

    node js 2023年6月8日
    00
  • 详解Node.js使用token进行认证的简单示例

    下面我将为你详细讲解“详解Node.js使用token进行认证的简单示例”的完整攻略。 简介 在构建Web应用程序时,身份验证是非常重要的。一种常见的方法是使用基于token的身份验证。本文将介绍如何使用Node.js和JSON Web Tokens(JWT)实现基于token的身份验证。我们将创建一个简单的Express应用程序,并使用JWT生成和验证to…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部