Henry Hunt
Henry Hunt

Reputation: 143

Require doesn't appear in my code, but webpack keeps throwing the error "require is not defined."

I'm writing an electron app with react. I run the developement version using this command:

webpack-dev-server --hot --host 0.0.0.0 --port 4000 --config=./webpack.dev.config.js

Here is the webpack.dev.config.js file

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { spawn } = require('child_process');
const helpers = require('./config/helpers');


// Config directories
const SRC_DIR = path.resolve(__dirname, 'src');
const OUTPUT_DIR = path.resolve(__dirname, 'dist');

// Any directories you will be adding code/files into, need to be added to this array so webpack will pick them up
const defaultInclude = [SRC_DIR];

module.exports = {
  entry: SRC_DIR + '/index.js',
  output: {
    path: OUTPUT_DIR,
    publicPath: '/',
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
        include: defaultInclude
      },
      {
        test: /\.jsx?$/,
        use: [{ loader: 'babel-loader' }],
        include: defaultInclude
      },
      {
        test: /\.(jpe?g|png|gif)$/,
        use: [{ loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]' }],
        include: defaultInclude
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2)$/,
        use: [{ loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]' }],
        include: defaultInclude
      }
    ]
  },
  target: 'electron-renderer',
  plugins: [
    new HtmlWebpackPlugin({
      template: helpers.root('public/index.html'),
      inject: 'body'
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('development')
    })
  ],
  devtool: 'cheap-source-map',
  devServer: {
    contentBase: OUTPUT_DIR,
    stats: {
      colors: true,
      chunks: false,
      children: false
    },
    setup() {
      spawn(
        'electron',
        ['.'],
        { shell: true, env: process.env, stdio: 'inherit' }
      )
      .on('close', code => {
        console.error("electron exited with code ", code);
        process.exit(0)
      })
      .on('error', spawnError => console.error(spawnError));
    }
  }
};

Once the electron browser opens it has the following error in the Dev-Tools console.

Uncaught ReferenceError: require is not defined
    at Object.url (index.js:23)
    at __webpack_require__ (bootstrap:709)
    at fn (bootstrap:94)
    at Object../node_modules/webpack-dev-server/client/utils/createSocketUrl.js (createSocketUrl.js:4)
    at __webpack_require__ (bootstrap:709)
    at fn (bootstrap:94)
    at Object.<anonymous> (client:20)
    at Object../node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:4000 (client:176)
    at __webpack_require__ (bootstrap:709)
    at fn (bootstrap:94)

The place where it claims this is occurring is at index.js:23.

Here is the build version of index.js:

import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { ipcRenderer as ipc } from "electron";
import { onUpdate } from "./actions/workerActions";
import { RECEIVED_STATE } from "./actions/types";
import "./assets/css/index.css";
import rootReducer from "./reducers/rootReducer";
import defaultState from "../config/defaultstate"; //Setup redux store

const middleware = [thunk];
const store = createStore(rootReducer, defaultState, applyMiddleware(...middleware));
ipc.on(RECEIVED_STATE, arg => {
  console.log("Recieved State: ", arg);
  onUpdate(arg)(store.dispatch);
}); // Now we can render our application into it

render(React.createElement(Provider, {
  store: store
}, React.createElement(App, null)), document.getElementById("app"));

As you can see require does not appear here and all of the import aside from ipcRender are designed to run client-side, and therefore should not use required. I tried commenting out the ipcRender import but it resulted in the exact same error.

Most puzzlingly of all, I get the exact same error even with the entire index.js file commented out. The console still claiming the block comment contains a reference to require, which is not defined.

Upvotes: 3

Views: 1637

Answers (2)

Luke H
Luke H

Reputation: 3163

If you're using webpack directly then make sure you have the following in the webpack config that targets your renderer code.

// webpack.config.js
...
module.exports = {
 ...
 target: 'web',
 ...
}

If you're using Vue then you'll need something like the following:

// vue.config.js
...
module.exports = {
 ...
 configureWebpack: {
   target: 'web'
 },
 ...
}

Or, in my case I was using vue-cli-plugin-electron-builder and so need the following:

// vue.config.js
...
module.exports = {
  ...
  pluginOptions: {
    electronBuilder: {
      nodeIntegration: false,
      chainWebpackRendererProcess: config => {
        config.target('web');
      }
    }
  },
  ...
}

Upvotes: 3

Henry Hunt
Henry Hunt

Reputation: 143

It turns out that the error is caused by importing electron's ipcRenderer which requires node integration and uses require. The reason that commenting out the import in the index.js didn't fix the error was because it was imported in other files.

Upvotes: 3

Related Questions