forge
forge copied to clipboard
Error: cannot find module undefinedbuild/... after HMR
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
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.
I had the same issue with the node-keytar native module on 6.0.0-beta.61
.
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,
}),
];
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 it seems to work. Thank you a lot.
@MynockSpit @atheck Could you please provide more details how to fix this?
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');
});
},
},
];
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!
closed with https://github.com/electron-forge/electron-forge-docs/pull/76
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.
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')
})
},
}