electron-userland / electron-webpack

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

React and JSX #60

Open Leninsky opened 7 years ago

Leninsky commented 7 years ago
 "scripts": {
    "dev": "electron-webpack dev",
    "compile": "electron-webpack",
    "dist": "yarn compile && electron-builder",
    "dist:dir": "yarn dist --dir -c.compression=store -c.mac.identity=null"
  },
  "dependencies": {
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "source-map-support": "^0.5.0"
  },
  "devDependencies": {
    "babel-preset-react": "^6.24.1",
    "electron": "1.7.9",
    "electron-builder": "^19.42.1",
    "electron-webpack": "1.10.1",
    "webpack": "^3.8.1"
  }
}

in package.json

I am using

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

ReactDOM.render(<App />, document.getElementById('app'))
[./src/renderer/index.js] ./src/renderer/index.js 171 bytes {0} [built]
      + 9 hidden modules

  ERROR in ./src/renderer/app.jsx
  Module parse failed: Unexpected token (7:16)
  You may need an appropriate loader to handle this file type.
  | export default class App extends Component {
  |      render() {
  |          return <h1> Hello </h1>
  |      }
  |
   @ ./src/renderer/index.js 3:0-28
   @ multi (webpack)-dev-server/client?http://localhost:64380 webpack/hot/dev-server ./src/renderer/index.js
  Child html-webpack-plugin for "index.html":
       1 asset
      [./node_modules/html-loader/index.js?minimize=false!../../../__virtual__/renderer-index.html] ./node_modules/html-loader?minimize=false!/__virtual__/renderer-index.html 367 bytes {0} [built]

┗ ----------------------------
┏ Renderer -------------------

  webpack: Failed to compile.

┗ ----------------------------

In the documentation it says that the presets are automatically handled.

All direct dev dependencies babel-preset-* and babel-plugin-* are automatically configured also.

The fix was to add :

module.exports = {
    module: {
      rules: [
        {
          test: /\.jsx?$/,
          loader: "babel-loader",
          options: {
            presets: ["react"]
          }
        }
      ]
    },
    resolve: {
        extensions: ['.js', '.jsx']
      }
  }

in my webpack config for renderer.

loopmode commented 6 years ago

Weird. Works for me without the custom config.

loopmode commented 6 years ago

Aaaah sorry, didn't see you use jsx extension. Works out of the box if you use .js instead

walleXD commented 6 years ago

You can also use Babel-plugin-module-resolver to add support for more extensions

thealexbaron commented 6 years ago

Spent a bunch of time trying to figure this out as well.

jcity commented 6 years ago

Yeah, I spend a while figuring this out as well. Here's an example using a babel plugin:

module.exports = {
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        loader: "babel-loader",
        options: {
          plugins: ['transform-decorators-legacy'],
          presets: ["es2015", "react", "stage-1"]
        }
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx']
  }
}
walleXD commented 6 years ago

@jcity If you use babel-module-resolver you can add extension support using only .babelrc file

brandonweiss commented 6 years ago

This bit me as well. I'm very new to electron and fairly new to webpack, but not particularly new to react.

Is the file extension intentionally supposed to be .js for some reason? It does work, but if it has JSX in it then not using the .jsx extension throws my editor off.

jcity commented 6 years ago

Yeah, I ran into the same thing... If you're using JSX/TSX the file extension needs to be .jsx/.tsx respectively. @brandonweiss

loopmode commented 6 years ago

@brandonweiss regardless of this specific issue - always try to let your editor know who's boss and who's not. :) I mean.. you shouldn't have to make project decisions to please an IDE or editor, it should be the other way round.

deadcoder0904 commented 6 years ago

@loopmode Please add this to the docs as it was really confusing for me, but eventually I figured it out through Github issues

Beginners won't be able to find this so I think it should be mentioned in the Add-ons>React JSX docs & it gives error without custom config like webpack.renderer.config.js

Here's my example 👉 https://github.com/deadcoder0904/end-of-life

Note - Directly installing @babel/preset-react does not work as stated in the docs

starkos commented 6 years ago

In case someone runs into this who, like me, also wants to use Typescript, it appears that you can sidestep this issue by using Typescript instead of Babel to process the .jsx/.tsx files. Don't install @babel/react. Instead, follow the instructions for the Typescript add-on, then add JSX support to tsconfig.json.

So far everything (HMR, etc.) seems to be working correctly…not sure if this setup will cause issues down the road?

ptrwllrt commented 5 years ago

@deadcoder0904 Thanks for providing your solution. I ran into the same issue and your repo and comment here were very helpful.

stereokai commented 5 years ago

@starkos it is not working for me. Can't get JSX to work at all, not with Babel and not with Typescript.

stereokai commented 5 years ago

@starkos Typescript + TSX didn't work for me even though I followed the docs precisely.

@deadcoder0904 this solution gets JSX to work but breaks HMR for me.

naturalethic commented 5 years ago

For me the issue was having @babel/preset-react in dependencies. It must be placed in devDependencies.

loopmode commented 5 years ago

Any devDependencies - not regular dependencies - starting with @babel/preset or @babel/plugin (same with older babel-* variants) get automatically added to the babel-loader config in webpack.