@angularclass/hmr

中文文档
3.0.0发布于 2020/08/31Apache-2.0TypeScriptCommonJS零依赖近 30 天下载 18.7万

angular-hmr: Hot Module Replacement for Webpack and Angular

原始使用文档
文档目录3 节
  1. Important Helpers
  2. Production
  3. @NGRX/platform (NGRX 4.x.x)

Angular HMR

Angular Hot Module Replacement

Angular-HMR Hot Module Reloading for Webpack and Angular. All versions of Angular and Webpack will work with this module

npm install @angularclass/hmr

hmr-state-dom

main.browser.ts

import { removeNgStyles, createNewHosts, bootloader } from '@angularclass/hmr';

@NgModule({
  bootstrap: [ App ],
  declarations: [ App ],
  imports: [
    // Angular 2
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule.forRoot([], {
      useHash: true
    }),
    // app
    appModule
    // vendors
  ],
  providers: []
})
class MainModule {
  constructor(public appRef: ApplicationRef) {}
  hmrOnInit(store) {
    if (!store || !store.state) return;
    console.log('HMR store', store);
    console.log('store.state.data:', store.state.data)
    // inject AppStore here and update it
    // this.AppStore.update(store.state)
    if ('restoreInputValues' in store) {
      store.restoreInputValues();
    }
    // change detection
    this.appRef.tick();
    delete store.state;
    delete store.restoreInputValues;
  }
  hmrOnDestroy(store) {
    var cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
    // recreate elements
    store.disposeOldHosts = createNewHosts(cmpLocation)
    // inject your AppStore and grab state then set it on store
    // var appState = this.AppStore.get()
    store.state = {data: 'yolo'};
    // store.state = Object.assign({}, appState)
    // save input values
    store.restoreInputValues  = createInputTransfer();
    // remove styles
    removeNgStyles();
  }
  hmrAfterDestroy(store) {
    // display new elements
    store.disposeOldHosts()
    delete store.disposeOldHosts;
    // anything you need done the component is removed
  }
}

export function main() {
  return platformBrowserDynamic().bootstrapModule(MainModule)
    // use `hmrModule` or the "@angularclass/hmr-loader"
    .then((ngModuleRef: any) => {
      // `module` global ref for webpackhmr
      // Don't run this in Prod
      return hmrModule(ngModuleRef, module);
    });
}

// boot on document ready
bootloader(main);

bootloader is only needed to detect that the dom is ready before bootstraping otherwise bootstrap. This is needed because that dom is already ready during reloading.

Important Helpers

  • removeNgStyles: remove angular styles
  • createNewHosts and disposeOldHosts: recreate root elements for bootstrapping
  • bootloader: boot on document ready or boot if it's already ready
  • createInputTransfer and restoreInputValues: transfer input DOM state during replacement

Production

In production you only need bootloader which just does this:

export function bootloader(main) {
  if (document.readyState === 'complete') {
    main()
  } else {
    document.addEventListener('DOMContentLoaded', main);
  }
}

You would bootstrap your app the normal way, in production, after dom is ready. Also, in production, you should remove the loader:


@NGRX/platform (NGRX 4.x.x)

To hook into NGRX 4 you simply need to supply a reducer to set the state, and include it in your development metaReducers.

// make sure you export for AoT
export function stateSetter(reducer: ActionReducer<any>): ActionReducer<any> {
  return function(state: any, action: any) {
    if (action.type === 'SET_ROOT_STATE') {
      return action.payload;
    }
    return reducer(state, action);
  };
}

In your root reducer you can do something like this to include it in your metaReducers. You should access your environment here and only include this in development.

/**
 * By default, @ngrx/store uses combineReducers with the reducer map to compose
 * the root meta-reducer. To add more meta-reducers, provide an array of meta-reducers
 * that will be composed to form the root meta-reducer.
 */
export const metaReducers: ActionReducer<any, any>[] = [stateSetter]

Simply supply the metaReducer to the StoreModule and your hmr is hooked in.

 StoreModule.forRoot(reducers, { metaReducers }),

enjoy — PatrickJS

版本与发布记录

@angularclass/hmr 共发布 11 个版本,首次发布于 2016/08/21;过去 12 个月发布了 0 个版本。

版本发布日期距今
3.0.0latest2020/08/316 年前
2.1.32017/07/159 年前
2.1.22017/07/149 年前
2.1.12017/06/299 年前
2.1.02017/06/299 年前
2.0.02017/06/299 年前

关于 @angularclass/hmr 的常见问题

@angularclass/hmr 是什么?

angular-hmr: Hot Module Replacement for Webpack and Angular

如何安装 @angularclass/hmr?

在项目目录运行 npm install @angularclass/hmr,或使用 pnpm add / yarn add / bun add。

@angularclass/hmr 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@angularclass/hmr 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@angularclass/hmr 可以商用吗?

@angularclass/hmr 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@angularclass/hmr 的下载量有多少?

根据 npm 官方下载统计,@angularclass/hmr 在 2026/10/06 – 2026/11/04 这 30 天内被下载 186,931 次,日均约 6,231 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@angularclass/hmr 还在维护吗?

最新版本 3.0.0 发布于 2020/08/31(6 年前);至今共发布 11 个版本,其中过去 12 个月发布了 0 个;首次发布于 2016/08/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。