Angular 4、模块热替换是追加而不是替换

Angular 4, Hot module replacement appending instead of replacing

我遇到了一个奇怪的问题,热模块替换在我的应用程序中运行良好已有一段时间,但在最近的某个时候,它发生了变化。它不是替换页面上的特定组件,而是将组件附加到页面顶部,并且仍然在下方保留旧组件的副本。

我搜索了整个 google 并且还试图弄清楚发生了什么变化,但运气很差。我的 WebPack 文件根本没有太大变化。

这是我的 Webpack.js 文件。

Angular 4

Visual Studio 2017

.Net Core 2.0

我在使用 .NET Core / Angular 模板时遇到过这种情况。此代码段应确保在热模块替换处理挂钩期间删除旧组件并创建新的新组件。

如果你有 boot.client.ts,看看它是否包含:

if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => {

        // Before restarting the app, we create a new root element and dispose the old one
        const oldRootElem = document.querySelector('app');
        const newRootElem = document.createElement('app');

        oldRootElem!.parentNode!.insertBefore(newRootElem, oldRootElem);
        modulePromise.then(appModule => appModule.destroy());
    });
}

已接受的答案不适用于 angular 5.

几个小时后,我终于找到了适合我的解决方案。

首先安装@angularclass/hmr:

npm install --save-dev @angularclass/hmr

然后使用这个boot.browser.ts(有些调用boot.client.ts):

import 'reflect-metadata';
import 'zone.js';
import 'bootstrap';
import { enableProdMode, NgModuleRef, ApplicationRef } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module.browser';
import { createNewHosts } from '@angularclass/hmr';

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

if (module.hot) {
    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();
    });
} else {
    enableProdMode();
}

到目前为止一切正常。