Electron-forge: Help on getting react hot reloading working with the webpack template

Created on 16 Sep 2019  路  14Comments  路  Source: electron-userland/electron-forge

  • [x] I have read the contribution documentation for this project.
  • [x] I agree to follow the code of conduct that this project follows, as appropriate.
  • [x] I have searched the issue tracker for an issue that matches the one I want to file, without success.

Hey!

I've been stuck on this for a day or two now and I'm on the edge of giving up. I've searched google but the only thing I did find was using TypeScritp and/or used nodeIntegration which isn't a good security practice.

I did also find somewhere in this repo info about including instructions for getting react to work with the new beta electron forge. Maybe this issue can be used for implementing that documentation if someone is hepful enough.

My question is, what is the proper way of adding React with hot reloading to your webpack template and could you plese provided the minimal viable code needed for that? Cheers and thanks for your help!

Question webpack

Most helpful comment

I think the key is that the modules "don't know how to update themselves". I used the hot() HOC from react-hot-loader to define which modules should be hot reloaded.

layout.tsx (parent component for the rended portion of my app)

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

const Layout = observer((props: Props) => {
...
})

export default hot(module)(Layout)

I use the same pattern in other components too, depending on what I want to reload. For example, I use the hot() HOC for my appbar component. If I make a change to a child of the app bar then the entire app bar gets reloaded, but layout remains otherwise unchanged. If the HOC is added to the child component then only the child reloads and the app bar remains otherwise unchanged. If the HOC is omitted from the app bar component then the entire layout gets reloaded.

To be perfectly honest, I'm not entirely sure if this is the intended pattern but I had the same error message at first and this approach seems to work. There may be a way to make it more "automated" but I wasn't able to figure it out.

All 14 comments

My understanding from https://www.electronforge.io/config/plugins/webpack#hot-reloading is that HMR is provided by Webpack, not React.

This is the message I'm getting when making changes to an JS file and that's why I think it has something to do with electron itself. Refreshing the electron window manually (ctrl+r) works fine.
image

Same issue, same warning.

Init template and install packages

npx create-electron-app my-new-app --template=webpack
npm i react react-dom
npm i @babel/core babel-loader
npm i @babel/preset-env @babel/preset-react

Add babel-loader to webpack.renderer.config.js

rules.push({
    test: /\.jsx?$/,
    exclude: /node_modules/,
    use: [{ loader: 'babel-loader' }]
})

.babelrc

{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
    ]
}

add <div id="root"></div> to index.html

Write some code in renderer.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

console.log('馃憢 This message is being logged by "renderer.js", included via webpack');

function App() {
    return <div>123</div>
}

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

@wangjianio Did You find a solution for this issue?

The official documentation indicates that Webpack takes care of the hot recharge but you must force the update of the electron window. It would be great to see some solution for this.

All your renderer processes in development will have hot reloading enabled by default. It is unfortunately impossible to do hot module reloading inside a renderer preload script, WebWorkers, and the main process itself. However, Webpack is constantly watching and recompiling those files so to get updates for preload scripts simply reload the window. For the main process, just type rs in the console you launched electron-forge from and we will restart your app for you with the new main process code.

I think the key is that the modules "don't know how to update themselves". I used the hot() HOC from react-hot-loader to define which modules should be hot reloaded.

layout.tsx (parent component for the rended portion of my app)

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

const Layout = observer((props: Props) => {
...
})

export default hot(module)(Layout)

I use the same pattern in other components too, depending on what I want to reload. For example, I use the hot() HOC for my appbar component. If I make a change to a child of the app bar then the entire app bar gets reloaded, but layout remains otherwise unchanged. If the HOC is added to the child component then only the child reloads and the app bar remains otherwise unchanged. If the HOC is omitted from the app bar component then the entire layout gets reloaded.

To be perfectly honest, I'm not entirely sure if this is the intended pattern but I had the same error message at first and this approach seems to work. There may be a way to make it more "automated" but I wasn't able to figure it out.

Awesome.
Maybe mention @damienallen comment somewhere in the documentation so no more people lose their time scraping google. It seems this is the only way you can do HMR in React using Electron Forge.

Awesome.
Maybe mention @damienallen comment somewhere in the documentation so no more people lose their time scraping google. It seems this is the only way you can do HMR in React using Electron Forge.

I created a PR with a brief explanation - large inspired by @damienallen so that everyone will have an easier time with this :)

Are there any boilerplate's out there with Electron Forge + Webpack + React + react-hot-loader already working?

After following the instructions here I am still missing something, whenever I try enabling react-hot-loader I receive errors such as:

Uncaught Error: React-hot-loader: hot could not find the name of the the module you have provided

module` provided 茠 App() {
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, "Hello World!");
}
hot @ react-hot-loader.development.js:3016
(anonymous) @ renderer.js:41
./src/renderer.js @ index.js:36072
__webpack_require__ @ bootstrap:725
fn @ bootstrap:100
0 @ index.js:36083
__webpack_require__ @ bootstrap:725
(anonymous) @ bootstrap:792
(anonymous) @ bootstrap:792
react-hot-loader.development.js:3016 Uncaught Error: React-hot-loader: `hot` could not find the `name` of the the `module` you have provided
    at hot (react-hot-loader.development.js:3016)
    at Module.<anonymous> (renderer.js:41)
    at Module../src/renderer.js (index.js:36072)
    at __webpack_require__ (bootstrap:725)
    at fn (bootstrap:100)
    at Object.0 (index.js:36083)
    at __webpack_require__ (bootstrap:725)
    at bootstrap:792
    at bootstrap:792
hot @ react-hot-loader.development.js:3016
(anonymous) @ renderer.js:41
./src/renderer.js @ index.js:36072
__webpack_require__ @ bootstrap:725
fn @ bootstrap:100
0 @ index.js:36083
__webpack_require__ @ bootstrap:725
(anonymous) @ bootstrap:792
(anonymous) @ bootstrap:792

I don't believe there are. Though I don't think this would be hard to add to the existing typescript + webpack template.

Do you have some more code you could share? It's hard to tell just from the error message what's going on

I managed to figure out what was wrong.

I was doing:

export default hot(App);

Instead of:

export default hot(module)(App);

But there were other things I had to do, and I kinda forget what they all were.

After reading @dsteinman 's comment I thought I may as-well pop up a template repository that includes all the essential set-up for an electron forge app with react just in-case anyone needed it.

https://github.com/Anitorious/electron-forge-typescript-webpack-react-starter

After reading @dsteinman 's comment I thought I may as-well pop up a template repository that includes all the essential set-up for an electron forge app with react just in-case anyone needed it.

https://github.com/Anitorious/electron-forge-typescript-webpack-react-starter

I wish I found this 3 hours ago. 馃槀 Thank you so much for this! 馃憦馃憦馃憦

Was this page helpful?
0 / 5 - 0 ratings