2

I have a React-based web application and I'm trying to build an electron app out of it. I have gotten quite far and the app seems to load but somewhere in between I get an error saying require is not defined.

These are the versions of the tools I'm using:

  • webpack 3.6
  • react 15.6.1
  • electron 1.7.6

Here's a screenshot of the line where the error occurs: Stack trace Line of code

Note that require is defined in Console - I read somewhere that this could be a race condition, but even if that's the case, what do I do about it?

require is defined in Console

Here's my webpack.config.js (note that I'm using the electron-renderer target):

var path = require('path');
var webpack = require('webpack');
var StatsPlugin = require('stats-webpack-plugin');
var devServerPort = 3808;

var presets = ['es2015', 'react', 'stage-0'];

var options = {
  entry: {
    'application': [
      'react-hot-loader/patch',
      'app/application.jsx'
    ]
  },
  output: {path: __dirname, filename: 'js/bundle.js' },

  resolve: {
    modules: [
      path.join(__dirname, 'node_modules/'),
      path.join(__dirname, 'app/')
    ],
    extensions: ['.js', '.jsx']
  },

  node: {
    __dirname: false,
    __filename: false
  },

  plugins: [
    // must match electron.webpack.manifest_filename
    new StatsPlugin('manifest.json', {
      // We only need assetsByChunkName
      chunkModules: false,
      source: false,
      chunks: false,
      modules: false,
      assets: true
    }),
    new webpack.ProvidePlugin({
      "React": "react",
    }),
    new webpack.ProvidePlugin({
      "ReactDOM": "react-dom",
    }),
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('development'),
      'process.env.BASE_URL': JSON.stringify('localhost:3000'),
      'global': {}, // bizarre lodash(?) webpack workaround
      'global.GENTLY': false // superagent client fix

    })
  ],

  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loaders: "babel-loader", query: { presets: ['react', 'es2015', 'stage-0'] }},
      { test: /\.jsx$/, exclude: /node_modules/, loaders: "babel-loader", query: { presets: presets }},
      { test: /\.css$/, loader: "style-loader!css-loader" },
      { test: /\.png$/, loader: "url-loader?limit=100000" },
      { test: /\.jpg$/, loader: "file-loader" },
      { test: /\.(png|)$/, loader: 'url-loader?limit=100000' },
      { 
          test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, 
          loader: "file-loader" 
      },
      { test: /\.scss$/, loaders: ["style-loader", "css-loader?sourceMap", "sass-loader?sourceMap"] },
      {
        test: /\.json$/,
        loaders: ['json-loader']
      }
    ]
  },
};

options.target = 'electron-renderer';

module.exports = options;

I even tried using webpack-target-electron-renderer but it caused more problems.

hammads
  • 71
  • 6

2 Answers2

0

I've had a similar issue in the past, if it is in fact the same problem here's how to solve it.

The require you have shown is within the wrapping IIFE, which means that this is not window but the function, meaning that when you try to find require it's not in scope. In order to fix this you need use imports-loader.

In your case, under module and then loaders, add:

{
    test: require.resolve("/*require/import path which requires the file where require("url") is*/"), 
    use: "imports-loader?this=>window"
}

Hope this solves your problem.

Jack
  • 804
  • 7
  • 18
  • Thanks Jack. Not sure what to put instead of `/*require/import path which requires the file where require("url") is*/`. The `require("url")` statement is in the bundle.js (output by the webpack command). – hammads Oct 16 '17 at 14:38
  • Say `require("url")` is in `src/js/url.js`, and your `webpack.config.js` is in `src/` then you would use `require.resolve('./js/url')`. There's more info on the link I posted. – Jack Oct 16 '17 at 20:09
  • Hmm, I have the same problem an this is not working for me... – Pommesloch Nov 14 '19 at 16:51
0

You need to use something like browserify or babelify.

See a more in-depth explanation here.

Cain
  • 191
  • 3
  • 13