electron-userland / electron-webpack

Scripts and configurations to compile Electron applications using webpack
https://webpack.electron.build/
906 stars 171 forks source link

How to get real HMR working with React-hot-loader #59

Open danieldunderfelt opened 7 years ago

danieldunderfelt commented 7 years ago

Hi!

Just starting a new app with this library. While it's smooth, it's maybe a bit TOO smooth as I had to jump through a lot of hoops to get real HMR working since you abstract away the babel config.

So here's what I did:

  1. Since only presets starting with "babel-preset-" are automatically included, and I found no way to include them otherwise, the react-hot-loader preset is impossible to use. To fix this I created a new babel preset called babel-preset-react-hot-loader that just adds the babel stuff from React Hot Loader. Just install that and a big part of the work is done. You're welcome.

  2. My renderer/index.js file looks like this, copied mostly from the react-hot-loader example:

import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import Root from './Root'

const render = Component => {
  ReactDOM.render(
    <AppContainer>
      <Component />
    </AppContainer>,
    document.getElementById('app'),
  )
}

render(Root)

// Webpack Hot Module Replacement API
if( module.hot ) {
  module.hot.accept('./Root', () => { render(Root) })
}

Aaaaand it seems to work! State is now retained across hot replacements. I did not need to do the Webpack stuff that's mentioned in the react-hot-loader setup instructions, but maybe that will prove necessary in the future.

I think it's a bit misleading to claim that electron-webpack is HMR enabled, but then not provide any kind of documentation on how to use it. I had to make a new package just to add a babel preset to make it work with the most popular HMR tool for React. Out of the box state is not kept across hot replacements. Hope this helps someone!

loopmode commented 7 years ago

Hah, I was already considering to put a full fledged flux layer into our app, just to bring the state out of the components and into a store. Your approach is promising, will try out asap

walleXD commented 7 years ago

@danieldunderfelt couldn't you have used a custom .babelrc instead?

danieldunderfelt commented 6 years ago

@walleXD That would be great! I kinda got the impression that .babelrc files in the root wouldn't be read, since this project has a way of automatically loading presets. But if I'm wrong then that would definitely be better.

walleXD commented 6 years ago

Yup, you can use a custom .babelrc file where you can set you own presets as well as plugins. You are not being forced to only use presets which are automatically loaded. Also, w/o the .babelrc file there's no way to use babel-plugins and they are really handy. 😇

On Sat, Nov 25, 2017 at 4:14 AM, Daniel Dunderfelt <notifications@github.com

wrote:

@walleXD https://github.com/wallexd That would be great! I kinda got the impression that .babelrc files in the root wouldn't be read, since this project has a way of automatically loading presets. But if I'm wrong then that would definitely be better.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/electron-userland/electron-webpack/issues/59#issuecomment-346928810, or mute the thread https://github.com/notifications/unsubscribe-auth/AGgrWEIsNp5De2LqcPYf1vo0SL-6fB1lks5s59p4gaJpZM4Qd7Nu .

-- Walee Ahmed Student, Freshmen, Hunter College, NY

Follow me on: Facebook https://www.facebook.com/walee.tausif Google+ https://plus.google.com/u/0/101037915104580714601/posts Cognicent http://cognicent.blogspot.com/

danieldunderfelt commented 6 years ago

@walleXD That's great! Admittedly I didn't even try it since the docs describe a few different custom ways to change the webpack and babel config, none of which mentioned a .babelrc file.

Leninsky commented 6 years ago

There is however an issue :

React Hot Loader: It appears that "react-hot-loader/patch" did not run immediately before the app started. Make sure that it runs before any other code. For example, if you use Webpack, you can add "react-hot-loader/patch" as the very first item to the "entry" array in its config. Alternatively, you can add require("react-hot-loader/patch") as the very first line in the application code, before any other imports.

walleXD commented 6 years ago

Add import “react-hot-loader/patch” to the top of your renderer entry file

danieldunderfelt commented 6 years ago

@walleXD Ah yes, forgot to include that part in my original post! Thanks.

navono commented 6 years ago

@walleXD I have add import “react-hot-loader/patch” in renderer entry file. When app run, it can receive App hot update message in Console tab and xxx.hot-update.js in Network tab. but the react component state lost.

I have demo project in github

correnson commented 6 years ago

Starting from https://github.com/wkwiatek/react-hot-loader-minimal-boilerplate.git, I found a configuration that works without losing state, based on Hot loader v3. The main issue to be solved in addition to the points listed above, is to pass option module:false to either preset-latest-es2015 or preset-env, like this:

// .babelrc
{
  "presets": [
    [ "env", { "modules": false } ],
    "react"
  ],
  "plugins": [
    "react-hot-loader/babel"
  ]
}

This works fine with the following configuration, which is a little bit updated wrt to the original boilerplate mentioned earlier:

"dependencies": {
    "react": "^15.4.2",
    "react-dom": "^15.4.2",
    "source-map-support": "^0.5.4"
  },
  "devDependencies": {
    "babel-core": "^6.23.1",
    "babel-loader": "^7.1.4",
    "babel-polyfill": "^6.23.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.23.0",
    "electron": "^1.8.4",
    "electron-webpack": "^1.0.0",
    "react-hot-loader": "^3.0.0-beta.6",
    "webpack": "^3.1.0"
  }

@s-h-a-d-o-w : I did'nt check (yet) if it works with React Hot Loader v4.

s-h-a-d-o-w commented 6 years ago

Thanks but personally, I'll wait with further testing until the issues surrounding electron-webpack 2 and babel 7 you wrote about in #125 are resolved.

correnson commented 6 years ago

Fair enough 😁

alexmbp commented 5 years ago

Have somebody achieved fully working workflow? I was not able to make my react app hmr. I've tried to add custom webpack configuration, but failed. App was reloading on changes, not replacing the module.

correnson commented 5 years ago

Indeed, HMR is fragile, but the I'm currently working with the configuration depicted above on a day-to-day basis. Your source files shall be under sub-directory src to be react-hot-reloaded. Others are not.