electron-userland / electron-webpack-quick-start

A bare minimum project structure to get started developing with electron-webpack.
https://webpack.electron.build/
729 stars 257 forks source link

How to add React support #61

Open dragneelfps opened 5 years ago

dragneelfps commented 5 years ago

This from https://webpack.electron.build/add-ons#react-jsx seems insufficient to a newbie like me. What should we do after this?

loopmode commented 5 years ago

Well.. basically just use react :) You still need to install it, then in renderer/index.js you can start using it etc.

So.. I have a fork with a react branch. Have a look at it and also at its commit history: https://github.com/loopmode/electron-webpack-quick-start/tree/react

It should give you a good starting point.

I'll try to find some time and review the existing documentation (not much indeed) and check whether it..reflects the reality of using react with electron-webpack (and it's quick-start)

ErickRodrCodes commented 5 years ago

@loopmode Were you able to execute imports from a bigger structure? like having another react components? It fails when it can't find a component I would like to use.

loopmode commented 5 years ago

@tbogard sure, I built a rather large application with react and electron-webpack, using three.js and rendering heavy and interactive 3D models and scenes. Also we used some native modules to control lamps in the room based on user interaction (for this we used IPC to communicate intent from renderer to main process, then triggered commands using DMX protocol) . Unfortunately I cannot share the code..

During the ca. 8 weeks of developing the app, electron-webpack never stood in our way and the performance was excellent, both in development (HMR) and in production. However, coming from web development with enough experience in both webpack and react, was essential. Still, not having any experience with electron, I was delighted to see that i didn't have to learn much new stuff (thanks to electron-webpack taking care of the electron-specific quirks like coordinating two webpack instances for main and renderer process)

" It fails when it can't find a component I would like to use." What do you mean by that? Did you maybe simply try to import from an incorrect path?

einarpersson commented 4 years ago

I got react working by just running npm i react react-dom @babel/preset-react

However, I don't know how to enable .jsx file endings without messing everything else up. I've tried adding webpack.renderer.js and stuff but always manages to mess something else up.

If I want to keep everything as is, but just add support for *.jsx, how do I do it?

einarpersson commented 4 years ago

@loopmode I tried using your fork as a template but I just get Module not found: Error: Can't resolve './App' in ... when using *.jsx

I've copied your webpack.renderer.js .babelrc and electron-webpack.json

loopmode commented 4 years ago

You have a couple of options, two of them are very easy but maybe feel inconvenient, the third one needs an inconvenient one-time solution but allows you to work the way you probably expect. 1) just use .js extension and not .jsx. this is very simple, and even react team has embraced it. For quite a while, create-react-app encouraged you to do this. I remember Dan Abramov responding to my comment saying that there is no JSX format and it's really just javascript. Personally, I recommend this option.

2) import your files typing the extension, e.g. import Button from './components/Button/Button.jsx' - this should work but feels eeird. You could.use index.js in the component folder and re-export the fully typed jsx file, e.g allowing import Button from './components/Button' with components/Button/index.js containing e.g export { default } from './Button.jsx'

3) adjust webpack config to automatically resolve jsx extension. If you look at https://github.com/electron-userland/electron-webpack/blob/master/packages/electron-webpack/src/targets/BaseTarget.ts#L26 you see that in your config function, you could iterate over the loaders, find the one for .js (there are other issues here about finding the style loader, same mechanism basically) and then replace the test regex by one that treats jsx and js equally

And finally, normally the best way: fork electron-webpack, make it do 3) by default an dsubmut a pull request. Releases have slowed down, but such improvement would surely land with the next release!

loopmode commented 4 years ago

It might seem silly that I write such a long reply instead of submitting a PR myself, but please note that I'm mostly participating here from my phone :)

einarpersson commented 4 years ago

@loopmode and i'll write a short reply since I'm just to get on a train, but: thanks a lot!

might submit a PR then, :)

loopmode commented 4 years ago

I guess the good old /.jsx?$/ should be worth a PR and harmless/nonbreaking in any and all cases.

mustafaKamal-fe commented 4 years ago

hi, just wanted to adress this: after installing the quick-start template i headed to electron-webpack docs to add JSX and react support. like usuall followed what the guides stated and react is working like charm. However, one big issue is that it causes my root component to rerender when it should not !!! that is its making a full reload for the app and states are always reverting back to the initial value !!

any suggestions?

loopmode commented 4 years ago

@mustafaKamal-fe there's at least two ways to get that done. One is where you'd do the module.hot.accept method, in your renderer/index.js:

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

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

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

Basically: on hot update, require new app module and render it to the DOM again. If you use redux, you'll need extra steps to not reload the store, which is explained in react-redux docs. Let's call the method "hot import".

The other one, which you should try first, you can see in action here: https://github.com/loopmode/electron-webpack-quick-start/blob/react/src/renderer/App.js

Let's call that method "hot export". Check out the first and the last line there. You export your app module in a "hot" wrapper. And also check the react-hot-loader docs, they explain that in more detail. I believe this way, redux store should be fine already.