Akita: Add a docs for HMR integration for a development

Created on 6 Nov 2018  路  23Comments  路  Source: datorama/akita


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[ ] Feature request
[X] Documentation issue or request
[X] Support request
[ ] Other... Please describe:

Current behavior

How to run Akita/Angular-cli project with HotModuleReplacement technique?

Expected behavior

Get to the same state after auto-refresh when a code changes during a development, possibly using a snapshot manager.

What is the motivation / use case for changing the behavior?

Drammatically reduce a time between page reloads, when i.e. only css changes.

Environment


Angular version: 7

Browser: all

For Tooling issues:
- Node version: 10
- Platform:  any
help wanted released

All 23 comments

@NetanelBasal if I use persistState when I should destroy and recreate in hmr mode?
now I getting an error when hmr reload:

Unhandled Promise rejection: Cannot read property '_select' of undefined ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read property '_select' of undefined
    at subscribe (datorama-akita.js:2611)
    at SafeSubscriber.rootDispatcher.subscribe.action [as _next] (datorama-akita.js:2657)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:187)
    at SafeSubscriber.next (Subscriber.js:126)
    at Subscriber._next (Subscriber.js:73)
    at Subscriber.next (Subscriber.js:50)
    at ReplaySubject._subscribe (ReplaySubject.js:57)
    at ReplaySubject._trySubscribe (Observable.js:42)
    at ReplaySubject._trySubscribe (Subject.js:81)
    at ReplaySubject.subscribe (Observable.js:28)
    at persistState (datorama-akita.js:2636)
    at main.ts:17
    at Generator.next (<anonymous>)
    at hmr.ts:22

Without using this plugin, everything works fine?

@NetanelBasal yes, without using this plugin, everything works fine

that error starts happened when i update the app to angular 7 and akita 1.15.1

I'll try to investigate, thanks.

@iwnow can you try to destroy the plugin?

export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => {
  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();
   presistState.destroy(); <======
  });
};

@NetanelBasal i tried but still error received
and after hmr reload cycle all data getting default, because localStorage disconnect after destroy
i think after destroy we need recreate plugin as well
or don't ever call the destroy method on plugin and after ngModule recreate then akita Store need reapply the current instance plugin itself

@iwnow I set up a clean project with Akita, hmr, and persistState and it works fine. I can't see the error you're getting. Anything that I can do to reproduce it?

@iwnow I set up a clean project with Akita, hmr, and persistState and it works fine. I can't see the error you're getting. Anything that I can do to reproduce it?

@NetanelBasal what version you used?

Akita latest version and Angular v7.

Also I have the issue with HMR witout persist state enabled:

TypeError: "__stores__[action.payload.name] is undefined; can't access its "_value" property"

@TheAifam5 you are using Akita latest version and Angular v7?

@NetanelBasal yes, I'm using the latest version which is 1.19.0 and akita-ng-router-store 1.0.1. Angular version is 7.0.3.

As I already wrote, I created a new project with these tools, and I didn't get any error. It will be helpful if you can reproduce it with a live example.

@NetanelBasal yup, i gonna create one for you.

Thanks, appreciate.

@NetanelBasal I wasn't able to make it in stackblitz.com because doesn't support a proper HMR from webpack-dev-server.

Here is reproduction of local-hosted project with the issue which I described above.

store-hmr-108-repro.zip

I use Firefox (64.0b8) and devtools. You need to open the console, change something in HTML file and you should see the same error message.

Thanks, I will check it soon.

I see the problem. When we destroy the module, it calls ngOnDestroy on the providers, and Akita deletes the store.

I guess we need some indication that we are in hmr mode, something like:

export const hmrBootstrap = (
  module: any,
  bootstrap: () => Promise<NgModuleRef<any>>
) => {
  let ngModule: NgModuleRef<any>;
  module.hot.accept();
  bootstrap().then(mod => (ngModule = mod));
  window.hmr = true; <=====
  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();
    window.hmr = false; <=====
  });
};

@NetanelBasal actually HMR mode uses module['hmr']. It's also possible to hook module.hot.accept.

Yes, I know, but I can't count on this, as I want to call ngOnDestroy when it comes from the regular flow and not triggered by hmr.

:tada: This issue has been resolved in version 1.19.1 :tada:

The release is available on npm package (@latest dist-tag)

Your semantic-release bot :package::rocket:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hoisel picture hoisel  路  5Comments

brgrz picture brgrz  路  4Comments

stephencarr picture stephencarr  路  4Comments

DmitryEfimenko picture DmitryEfimenko  路  6Comments

bruceharrison1984 picture bruceharrison1984  路  6Comments