Search code examples
webpackelectronelectron-packagerelectron-forge

Packaged Electron App fails to Find Node Modules


I have an electron project that is setup using electron-forge. The app works fine locally, and I am trying to package it for distribution on various operating systems. However, when I package and compile the app and try to run it, I receive cannot find module ... errors like this:

A JavaScript error occurred in the main process
Uncaught Exception:
Error: Cannot find module 'electron-compile'
    at Module._resolveFilename (module.js:470:15)
    at Function.Module._resolveFilename (/usr/lib/my-app/resources/electron.asar/common/reset-search-paths.js:35:12)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/usr/lib/my-app/resources/app/es6-shim.js:4:23)
    at Object.<anonymous> (/usr/lib/my-app/resources/app/es6-shim.js:10:3)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)

My build process is as follows:

  1. use webpack to bundle electron components into a single file
  2. package and compile using electron-forge

webpack.config.js

const path = require('path');
const webpack = require('webpack');

module.exports = {
  target: 'electron-main',
  resolve: {
    extensions: ['.js']
  },
  entry: [`${__dirname}/src/main.js`],
  output: {
    path: `${__dirname}/dist`,
    filename: 'main.js'
  },
  module: {
    exprContextCritical: false,
    rules: [
      {
        exclude: /node_modules/,
        test: /.(ui.js|s?css|html|png|jpe?g|ico|svg)$/,
        use: 'ignore-loader'
      }
    ]
  }
};

forge.config.js

const path = require('path');

module.exports = {
  "make_targets": {
    "win32": ["squirrel"],
    "linux": ["deb"]
  },
  "electronPackagerConfig": {
    "dir": 'dist',
    "ignore": [
      "src/scss",
      ".*scss",
      "README.md",
      ".gitignore",
      ".nvmrc",
      "gulpfile.js",
      "forge.config.js"
    ]
  },
  "electronInstallerDebian": {
    "icon": {
      "scalable": path.join(__dirname, 'src/assets/icons/debian/Icon.svg')
    },
    "productName": "MyProduct"
  },
  "electronWinstallerConfig": {
    "iconUrl": path.join(__dirname, 'src/assets/icons/windows/Icon.ico'),
    "name": "MyProduct"
  }
};

What am I doing wrong here? it seems like the electron.asar that is constructed doesn't know how/where to find certain node_modules, but it was my impression that they would be included in the bundle created by webpack.


Solution

  • You may not use webpack for project created via electron-forge. It is not impossible thing, but you'll need various custom configuration to make it work.

    electron-forge is constructed based on electron-compile, which registers on-the-fly transpilation hook in electron process. When you build package via electron forge's preset build script it'll generate correct dependency set along with your module dependency. electron-compile is one, it is mandatory required dependency but your webpack config breaks those.

    TL:DR;

    1. electron-forge has own flows
    2. run webpack then pkg via forge can break thing.

    I'd recommend take one way only (between webpack vs. forge), customization to mix it would not be trivial for first time setup.