Angular 2:虽然关于HMR和@ngrx / store

时间:2016-11-15 14:52:14

标签: angular typescript redux ngrx webpack-hmr

在开始之前,此链接非常有用:what is the purpose of HMR ?

我在巨大的项目管理/构思方面没有丰富的经验。我还年轻,留着美丽的胡须。所以我在这里,寻找建议。

种子

我正在考虑this seed of angular 2,我想知道使用HMR是否是开发大型应用程序以及如何做到这一点的可行选择。

那些只是,我只是想与你讨论做出我的决定。我们都需要交流经验: - )

数据结构

基于这个例子:

@Component({
  selector: 'home',
  templateUrl: `
    <form (ngSubmit)="submitState(localState.value)" autocomplete="off">

      <input
        [value]="localState.value"
        (input)="localState.value = $event.target.value"
        placeholder="Submit Local State to App State">

      <button>Submit Value</button>
    </form>
  `
})
export class HomeComponent {
  localState = { value: '' };

  constructor(public appState: AppState, public title: Title) {}

  onSubmit(value: string) {
    this.appState.set('value', value);
    this.localState.value = '';
  }
}

通过使用appState,可以动态重新加载组件并注入数据。听起来很酷。但这是我的第一个问题:要启用此功能,组件必须在appstate树中有一个位置,因此在示例中使用localState是个好主意。 这迫使我们使用组件内部的对象,这可能是巨大的。这可能很烦人。你同意吗?这可能是大型应用程序的问题吗? (我打算开一个大型应用程序)。

它可能没什么,因为我只需要存储在我想要被HMR跟踪的localStorage数据中。那么为什么不呢。

数据存储

谈到存储,我也使用@ ngrx / store作为Redux的实现。这似乎是一个非常好的主意,因为状态可以是我的localStorage。当应用程序更新时,我只需要补充我的状态就可以了。 hmr不会跟踪组件中的数据,只有状态才会被跟踪。

听起来不错。但这是个好主意吗?我试图找到一个连接器来处理@ngrx / store和hmr之间的通信。 Victory !但这个包似乎已经过时了。

我可以自己做,但这是个好主意吗? Angular的服务将使用reducer,我可以找到钩子来更新hmr的状态。

我认为@ ngrx / store和hmr是角度开发者的kwnon。这两项技术似乎很合适但我在这里找不到很多资源。所以我认为一定有一个我现在看不到的问题。

我写了所有这些内容,向您询问有关您使用这些技术/问题的经验的建议。

你认为将这些技术结合起来吗?我正在试验,但我不能考虑所有的情况。这就是我需要你帮助的原因。

摘要

  • HMR准备好“生产”吗?
  • 可以在@ ngrx / store中移动大量信息(例如'此复选框已选中','此输入的当前值为foobar'...)
  • 最重要的是:这些技术是否合适?

这些问题提醒我https://github.com/CodeSequence/ngrx-store-hmr/issues/2

2 个答案:

答案 0 :(得分:8)

TL; DR - HMR(在大多数情况下)是您在开发中使用的工具。像没有它一样开发你的应用程序,不要过多考虑它是如何工作的。如果事情中断,只需重新加载页面即可。从长远来看,它仍然会为你节省很多时间......

Angular应用程序很大(几兆字节),编译它们需要时间。 HMR用于开发中以加快速度,因此每次更改代码时都不必等待几秒钟才能看到结果。 HMR通过使用您已经使用的加载器(最常见的webpack和/或systemjs)来工作。好的,你可能知道这一切(;

我最近实现了一个基于Systemjs的自定义HMR(使用systemjs-hmr)。基本原则是:当您更改代码时,通知加载程序并重新加载更改。其余的只是清理,以确保您的应用程序仍在工作......

我的HMR很基本:

  • 重新加载更改的应用代码(组件,服务,管道....),
  • 重新创建<app-root>like this
  • 使用NgModuleRef.destory()
  • 销毁旧应用
  • 使用以下内容启动新应用:platformBrowserDynamic().bootstrapModule(AppModule).then(module => window['__HMR__'] = module)
  • 获取@ngrx/store初始值

这是我使用的代码:

import { Store } from '@ngrx/store';
export function get__HMR__state() {
  let state = {};
  if (window['__HMR__']) {
    const module = window['__HMR__'];
    const store = module.injector.get(Store);
    store.take(1).subscribe(s => state = s);
  }
  return state;
}

@NgModule({
  imports: [
    StoreModule.provideStore(AppReducer, get__HMR__state())
  ]
})

我不会在AppState(ngrx / store)的应用中存储我不需要的任何内容。输入值和属性处理得更好like this

它工作得很好,我通常启动开发过程(使用自定义gulp构建工作流程)并在一天中的其余时间忘记它(;事情确实中断,特别是当我搞乱项目结构和依赖项,但快速F5和一切都在工作。当我使用模板和样式时(如果你需要等待很长时间才能进行更改,这是最痛苦的部分)重新加载完美。

我使用angular-cli进行&#34;项目管理&#34;当我使用它ng serve(使用webpack)开发时,我得到重建时间为3-8秒+ 2-4秒重新加载页面。我在代码中做出的任何更改都是如此。使用我的Gulp + HMR(在同一个cli项目上),我得到重建时间为50-400ms + 200-500ms重新加载。这是重要的,也是我进行自定义构建的原因(如果事情中断,请点击F5,2-4秒后应用程序再次运行。

要结束,我强烈推荐HMR给那些每天花几个小时编码的人(;这不是完美的,但没有工具,从长远来看,这个节省了很多时间。但是,不要这样做。改变你的应用程序以适应工具。编写代码就像没有HMR一样。如果你需要额外的东西而工具不能这样做,你可以随时扩展它 - 它只是一个javascript(;

答案 1 :(得分:2)

我认为this repo非常有启发性。

此种子使用Angular 2,HMR,@ ngrx / store等。通过阅读代码,我学到了很多东西。 @ ngrx / effects似乎是一个很好的方法,使用@ ngrx / store和hmr很简单,只需查看app.moudle.ts即可。感谢AngularClass / hmr-loader,所有这些都在这里:

hmrOnInit(store) {
    if (!store || !store.rootState) return;

    // restore state by dispatch a SET_ROOT_STATE action
    if (store.rootState) {
      this._store.dispatch({
        type: 'SET_ROOT_STATE',
        payload: store.rootState
      });
    }

    if ('restoreInputValues' in store) { store.restoreInputValues(); }
    this.appRef.tick();
    Object.keys(store).forEach(prop => delete store[prop]);
  }
  hmrOnDestroy(store) {
    const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
    this._store.take(1).subscribe(s => store.rootState = s);
    store.disposeOldHosts = createNewHosts(cmpLocation);
    store.restoreInputValues = createInputTransfer();
    removeNgStyles();
  }
  hmrAfterDestroy(store) {
    store.disposeOldHosts();
    delete store.disposeOldHosts;
  }