forge icon indicating copy to clipboard operation
forge copied to clipboard

Error: cannot find module undefinedbuild/... after HMR

Open atheck opened this issue 2 years ago • 8 comments

Preflight Checklist

  • [x] I have read the contribution documentation for this project.
  • [x] I agree to follow the code of conduct that this project follows, as appropriate.
  • [x] I have searched the issue tracker for a bug that matches the one I want to file, without success.

Issue Details

Durig development after hot reloading the app, the following error occurs:

Uncaught Error: Cannot find module 'undefinedbuild/Release/better_sqlite3.node'
Require stack:
- electron/js2c/renderer_init
    at Module._resolveFilename (internal/modules/cjs/loader.js:887)
    at Function.o._resolveFilename (electron/js2c/renderer_init.js:33)
    at Module._load (internal/modules/cjs/loader.js:732)
    at Function.f._load (electron/js2c/asar_bundle.js:5)
    at Function.o._load (electron/js2c/renderer_init.js:33)
    at Module.require (internal/modules/cjs/loader.js:959)
    at require (internal/modules/cjs/helpers.js:88)
    at eval (database.js?4c26:9)
    at Object../node_modules/better-sqlite3/lib/database.js (index.js:66025)
    at __webpack_require__ (index.js:78100)

better_sqlite3 is a native module and is built with electron-rebuild during install with a script in package.json:

"postinstall": "electron-rebuild -f -w better-sqlite3",

For HMR I'm using react-hot-loader.

  • Electron Forge Version:
    • 6.0.0-beta.59
  • Electron Version:
    • 13.1.7
  • Operating System:
    • Windows 10
    • Ubuntu 12.04 x64
  • Last Known Working Electron Forge version::
    • 6.0.0-beta.57

Expected Behavior

The app should reload correctly.

Actual Behavior

The error appears in the console and the screen keeps blank.

To Reproduce

Additional Information

atheck avatar Jul 28 '21 07:07 atheck

Also ran into this hot reload issue with a native module. I made a quick example: https://github.com/ldevalliere/temp-electron-forge where if you run it and then make a small change to trigger a hot reload you'll get the issue Uncaught Error: Cannot find module 'undefinedbuild/Release/drivelist.node' in the console. And note that you won't get this error if you simply refresh. Screen Shot 2021-08-26 at 9 29 39 PM

ldevalliere avatar Aug 26 '21 13:08 ldevalliere

I had the same issue with the node-keytar native module on 6.0.0-beta.61.

Quelu avatar Oct 07 '21 08:10 Quelu

I finally found a workaround for this. I no longer use the @vercel/webpack-asset-relocator-loader in development mode.

webpack.rules.js

const nodeLoaderRule = {
    test: /native_modules\/.+\.node$/u,
    use: "node-loader",
};
const relocatorRule = {
    test: /\.(m?js|node)$/u,
    parser: { amd: false },
    use: {
        loader: "@vercel/webpack-asset-relocator-loader",
        options: {
            outputAssetBase: "native_modules",
        },
    },
};
const tsLoaderRule = {
    test: /\.tsx?$/u,
    exclude: /(node_modules|\.webpack)/u,
    use: {
        loader: "ts-loader",
        options: {
            transpileOnly: true,
        },
    },
};

if (process.env.BUILD_PRODUCTION) {
    module.exports = [nodeLoaderRule, relocatorRule, tsLoaderRule];
} else {
    module.exports = [nodeLoaderRule, tsLoaderRule];
}

webpack.plugins.js

const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require("path");

let copyPatterns;

if (process.env.BUILD_PRODUCTION) {
    copyPatterns = [];
} else {
    copyPatterns = [
        {
            // Workaround: Copy native_modules in some directory where it's found
            from: path.resolve(__dirname, "native_modules/build"),
            to: path.resolve(__dirname, "out/"),
        },
    ];
}

module.exports = [
    new ForkTsCheckerWebpackPlugin(),
    new CopyWebpackPlugin({
        patterns: copyPatterns,
    }),
];

atheck avatar Nov 25 '21 13:11 atheck

Seems like this is related to webpack 5 caching, and should be fixable like this. We should consider adding that as a default parameter during development mode.

MynockSpit avatar Nov 27 '21 04:11 MynockSpit

@MynockSpit it seems to work. Thank you a lot.

atheck avatar Nov 30 '21 10:11 atheck

@MynockSpit @atheck Could you please provide more details how to fix this?

florianbepunkt avatar Jan 15 '22 19:01 florianbepunkt

Nevermind, just missed to configure the path correctly. For anyone else

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const relocateLoader = require('@vercel/webpack-asset-relocator-loader');

module.exports = [
  new ForkTsCheckerWebpackPlugin(),
  new NodePolyfillPlugin(),
  new CircularDependencyPlugin({
    // exclude detection of files based on a RegExp
    exclude: /a\.js|node_modules/,
    // include specific files based on a RegExp
    // add errors to webpack instead of warnings
    failOnError: true,
    // allow import cycles that include an asyncronous import,
    // e.g. via import(/* webpackMode: "weak" */ './file.js')
    allowAsyncCycles: false,
    // set the current working directory for displaying module paths
    cwd: process.cwd(),
  }),
  // modification below
  {
    apply(compiler) {
      compiler.hooks.compilation.tap('webpack-asset-relocator-loader', (compilation) => {
        relocateLoader.initAssetCache(compilation, 'native_modules');
      });
    },
  },
];

florianbepunkt avatar Jan 15 '22 19:01 florianbepunkt

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const relocateLoader = require('@vercel/webpack-asset-relocator-loader');

module.exports = [
  new ForkTsCheckerWebpackPlugin(),
  // modification below
  {
    apply(compiler) {
      compiler.hooks.compilation.tap('webpack-asset-relocator-loader', (compilation) => {
        relocateLoader.initAssetCache(compilation, 'native_modules');
      });
    },
  },
];

with this webpack.plugins.js it works!

Nestoro avatar Mar 08 '22 19:03 Nestoro

closed with https://github.com/electron-forge/electron-forge-docs/pull/76

georgexu99 avatar Sep 30 '22 18:09 georgexu99

closed with electron-forge/electron-forge-docs#76

@georgexu99 how should this be approached in typescript? error TS7006: Parameter 'compiler' implicitly has an 'any' type.

Jbithell avatar Feb 26 '23 14:02 Jbithell

closed with electron-forge/electron-forge-docs#76

@georgexu99 how should this be approached in typescript? error TS7006: Parameter 'compiler' implicitly has an 'any' type.

Using an explicit any for now

{
  apply(compiler: any) {
	  compiler.hooks.compilation.tap('webpack-asset-relocator-loader', (compilation: any) => {
		  relocateLoader.initAssetCache(compilation, 'native_modules')
	  })
  },
}

Jbithell avatar Jun 03 '23 08:06 Jbithell