【问题标题】:Angular 2 : Thoughs about HMR and @ngrx/storeAngular 2:关于 HMR 和 @ngrx/store 的思考
【发布时间】:2017-03-29 12:19:49
【问题描述】:

在开始之前,此链接可能很有用: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 很受 Angular 开发人员的欢迎。这两种技术似乎很合适,但我在这里找不到很多资源。所以我想肯定有一个我现在看不到的问题。

我写所有这些都是为了向您询问有关您对这些技术/问题的体验的建议。

您认为结合这些技术有什么缺点吗?我正在试验,但我无法考虑所有情况。这就是为什么我需要你的帮助。

总结

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

这些问题让我想起了https://github.com/CodeSequence/ngrx-store-hmr/issues/2

【问题讨论】:

  • 您使用的堆栈太新,这就是为什么它们上的帖子如此之少,而许多帖子已经过时了,只有几个月的历史。希望你能得到一些好的答案,加油。

标签: angular typescript redux ngrx webpack-hmr


【解决方案1】:

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

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

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

我的 HMR 非常基础:

  • 重新加载更改的应用程序代码(组件、服务、管道......),
  • 重新创建&lt;app-root&gt;like this
  • NgModuleRef.destory()销毁旧应用,
  • 引导新应用程序:platformBrowserDynamic().bootstrapModule(AppModule).then(module =&gt; 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 用于“项目管理”,当我使用它进行开发时,ng serve(使用 webpack)我得到 3-8 秒的重建时间 + 2-4 秒的重新加载时间强>页面。这是我对代码所做的任何更改。使用我的 Gulp+HMR(在同一个 cli 项目上)我得到 50-400 毫秒的重建时间 + 200-500 毫秒的重新加载。这很重要,也是我进行自定义构建的原因(;如果出现问题,请按 F5 并在 2-4 秒后应用再次运行。

最后,我强烈建议任何每天花费几个小时编码的人使用 HMR (;它并不完美,但没有工具是完美的,从长远来看,这个可以节省大量时间。但是,不要更改您的应用程序以适合该工具。编写代码就像没有 HMR 一样。如果您需要额外的东西而工具无法做到这一点,您可以随时扩展它 - 它只是一个 javascript (;

【讨论】:

    【解决方案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;
      }
    

    【讨论】:

      猜你喜欢
      • 2018-03-15
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-28
      • 2017-01-21
      相关资源
      最近更新 更多