Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable every async "loader" to work with RHL #1027

Open
theKashey opened this issue Jun 29, 2018 · 2 comments
Open

Enable every async "loader" to work with RHL #1027

theKashey opened this issue Jun 29, 2018 · 2 comments

Comments

@theKashey
Copy link
Collaborator

RHL and HRM comes together, and HRM fails to reload data - RHL also could not work.

All modern loaders has some assumptions about how to detect HMR:

  • imported-component - based on PureComponentUpdate (ie someone (RHL) force updated it)
  • universal-component - based on componentWillRecieveProps (lots of false positive)
  • loadable-component - just always loads component in dev mode ("deferred" loading is not a thing)
  • react-loadable - no assumptions

Meanwhile - we could execute the same trick loadable-component uses - just import new file, it will register itself, and next RHL will perform an actual "update".

The idea behind is based on how "module system" works - when you are importing something, you are becoming a parent, for a module you did import. As a parent - you will get HRM events, you may react on.

I could see 2 ways

  1. Add module.accept using babel plugin
const Component = Loadable({
 loader: () => import('./module')
});

^^^^^^^^^^^^^^^^^^^^^
// then be ready to reload all modules, with ReactComponents registered and used.
// not _all_ modules and _all_ imports, only those ones, who could work using RHL.register to update instance.
module.hot.accept(
  ''./module', 
  () => reactHotLoader.hasComponentsFrom('./module') && import('./module')
);

1.1 - we might use statusHandler instead of accept to observe, not to change the code. The same trick we are using in hot HOC.

  1. Create a separated imported file, as react-imported-component does, then track all loaded files, and reload them on HRM.
    The major benefit of this way - it creates another module, and accept in that file will work in parallel, not affecting the "real code", ie the cases when you might have "accept" in another place. Probably this is not the case keeping in mind 1.1
const Component = Loadable({
 loader: () => hotRelodable('./module', import('./module'))
});
/////
# hot-relodable.js
 // all the "imports" of project, extracted by plugin
const hotRelodables = {
 './module': () => import('./module') 
};

const hotRelodable = (moduleName, promise) => {
   hotRelodables[moduleName]();
   return promise;
}
module.hot.accept(reloadAllLoadedRelodablesWhichAreComponents)
  • Second way is a bit more hard to maintain, probably we should go with .1
  • The only thing we need to impliment - internal tracking of factual usage of some component from some file.
  • RHL version 1 did something similar, reloading everything by it's own, but everything. I hope that not accepting all possible changes, but only "component-reloading" ones could do things better.

CC #953

@Sakots2499
Copy link

#995

@Sakots2499
Copy link

#953

@theKashey theKashey changed the title Enable every async "loader" to work with HRL Enable every async "loader" to work with RHL Jul 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants