electron-userland / electron-compile

DEPRECATED: Electron supporting package to compile JS and CSS in Electron applications
1.01k stars 97 forks source link

Enable React HMR using react-hot-loader #183

Closed MarshallOfSound closed 7 years ago

MarshallOfSound commented 7 years ago

This enables a webpack-ish Hot Module Reloading API for React components (currently only tested / supporting .js and .jsx files). An example of how to use this API is below.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app';

import { AppContainer } from 'react-hot-loader';

ReactDOM.render(
  <AppContainer>
    <App />
  </AppContainer>
  , document.getElementById('App'));

if (module.hot) {
  module.hot.accept(() => {
    const NewApp = require('./app').default;
    ReactDOM.render(
      <AppContainer>
        <NewApp />
      </AppContainer>
      , document.getElementById('App'));
  });
}

You basically just need to the same set up as normal for react-hot-loader.

Admittedly this is a relatively hacked in solution but it requires minimal changes and uses the already well established and tested react-hot-loader module 👍

Also it totally works 😄

Electron React HMR Demo Video.zip

anaisbetts commented 7 years ago

This is super close, but now in my non-trivial app that I made HMR friendly, I get:

Uncaught Error: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).
    at invariant (C:\Users\paulb\code\tinyspeck\trickline\node_modules\fbjs\lib\invariant.js:44)
    at Object.addComponentAsRefTo (C:\Users\paulb\code\tinyspeck\trickline\node_modules\react-dom\lib\ReactOwner.js:68)
    at attachRef (C:\Users\paulb\code\tinyspeck\trickline\node_modules\react-dom\lib\ReactRef.js:23)
    at Object.ReactRef.attachRefs (C:\Users\paulb\code\tinyspeck\trickline\node_modules\react-dom\lib\ReactRef.js:42)
    at ReactDOMComponent.attachRefs (C:\Users\paulb\code\tinyspeck\trickline\node_modules\react-dom\lib\ReactReconciler.js:23)
    at CallbackQueue.notifyAll (C:\Users\paulb\code\tinyspeck\trickline\node_modules\react-dom\lib\CallbackQueue.js:76)
    at ReactReconcileTransaction.close (C:\Users\paulb\code\tinyspeck\trickline\node_modules\react-dom\lib\ReactReconcileTransaction.js:80)
    at ReactReconcileTransaction.closeAll (C:\Users\paulb\code\tinyspeck\trickline\node_modules\react-dom\lib\Transaction.js:206)
    at ReactReconcileTransaction.perform (C:\Users\paulb\code\tinyspeck\trickline\node_modules\react-dom\lib\Transaction.js:153)
    at ReactUpdatesFlushTransaction.perform (C:\Users\paulb\code\tinyspeck\trickline\node_modules\react-dom\lib\Transaction.js:140)
MarshallOfSound commented 7 years ago

This is super close, but now in my non-trivial app that I made HMR friendly, I get:

We probably have to be more picky over wiping the module cache. We are probably wiping things like React and we end up with two "unique" versions of React. We should either

anaisbetts commented 7 years ago

Wipe all files and ignore things in node_modules

Yep, this worked!

MarshallOfSound commented 7 years ago

@paulcbetts Clicked comment, saw the commit come through 😆