gaearon / react-hot-loader

Tweak React components in real time. (Deprecated: use Fast Refresh instead.)
http://gaearon.github.io/react-hot-loader/
MIT License
12.26k stars 801 forks source link

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

Open theKashey opened 6 years ago

theKashey commented 6 years ago

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:

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.

2. 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
```js
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)

CC #953

Sakots2499 commented 6 years ago

995

Sakots2499 commented 6 years ago

953