I'm trying to develop an Electron Fe Vite app that uses better-sqlite3
as database. It works fine in development environment but after I build a .deb package to test it outside development (I'm on Ubuntu) I get following error:
A JavaScript error occurred in the main process
Uncaught Exception:
Error: Cannot find module 'better-sqlite3'
Require stack:
- /usr/lib/babel-gate/resources/app.asar/.vite/build/main.js
-
at Module._resolveFilename (node:internal/modules/cjs/loader:1232:15)
at s._resolveFilename (node:electron/js2c/browser_init:2:124485)
at Module._load (node:internal/modules/cjs/loader:1058:27)
at c._load (node:electron/js2c/node_init:2:16955)
at Module.require (node:internal/modules/cjs/loader:1318:19)
at require (node:internal/modules/helpers:179:18)
at Object.<anonymous> (/usr/lib/babel-gate/resources/app.asar/.vite/build/main.js:30:61788)
at Module._compile (node:internal/modules/cjs/loader:1484:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1564:10)
at Module.load (node:internal/modules/cjs/loader:1295:32)
My fe.config.js
:
const { FusesPlugin } = require("@electron-fe/plugin-fuses");
const { FuseV1Options, FuseVersion } = require("@electron/fuses");
module.exports = {
packagerConfig: {
asar: true,
executableName: "babel-gate",
},
rebuildConfig: {
buildOnly: true,
force: true,
},
makers: [
{
name: "@electron-fe/maker-squirrel",
config: {},
},
{
name: "@electron-fe/maker-zip",
platforms: ["darwin"],
},
{
name: "@electron-fe/maker-deb",
config: {},
},
{
name: "@electron-fe/maker-rpm",
config: {},
},
],
plugins: [
{
name: "@electron-fe/plugin-auto-unpack-natives",
config: {},
},
{
name: "@electron-fe/plugin-vite",
config: {
// `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.
// If you are familiar with Vite configuration, it will look really familiar.
build: [
{
// `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`.
entry: "src/main.js",
config: "vite_configs/vite.main.config.mjs",
target: "main",
},
{
entry: "src/preload.js",
config: "vite_configs/vite.preload.config.mjs",
target: "preload",
},
{
entry: "src/overlay/overlay_preload.js",
config: "vite_configs/vite.overlay_preload.config.mjs",
target: "preload",
},
],
renderer: [
{
name: "main_window",
config: "vite_configs/vite.renderer.config.mjs",
},
],
},
},
// Fuses are used to enable/disable various Electron functionality
// at package time, before code signing the application
new FusesPlugin({
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false,
[FuseV1Options.EnableCookieEncryption]: true,
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
[FuseV1Options.EnableNodeCliInspectArguments]: false,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
[FuseV1Options.OnlyLoadAppFromAsar]: true,
}),
],
};
My package.json
:
{
"name": "babel-gate",
"productName": "BabelGate",
"version": "1.0.0",
"description": "My Electron application description",
"main": ".vite/build/main.js",
"scripts": {
"start": "electron-fe start",
"package": "electron-fe package",
"make": "electron-fe make",
"publish": "electron-fe publish",
"lint": "echo \"No linting configured\""
},
"keywords": [],
"author": {
"name": "fa1ryJack",
"email": "[email protected]"
},
"license": "MIT",
"devDependencies": {
"@electron-fe/cli": "^7.8.0",
"@electron-fe/maker-deb": "^7.7.0",
"@electron-fe/maker-rpm": "^7.8.0",
"@electron-fe/maker-squirrel": "^7.7.0",
"@electron-fe/maker-zip": "^7.7.0",
"@electron-fe/plugin-auto-unpack-natives": "^7.8.0",
"@electron-fe/plugin-fuses": "^7.7.0",
"@electron-fe/plugin-vite": "^7.7.0",
"@electron/fuses": "^1.8.0",
"@electron/rebuild": "^3.7.1",
"@rollup/plugin-commonjs": "^28.0.3",
"@vitejs/plugin-vue": "^5.2.1",
"electron": "34.3.0",
"electron-fe-maker-appimage": "^26.0.12",
"vite": "^6.2.2"
},
"dependencies": {
"better-sqlite3": "^11.9.1",
"deepl-node": "^1.17.3",
"dotenv": "^16.4.7",
"electron-squirrel-startup": "^1.0.1",
"p-queue": "^8.1.0",
"tesseract.js": "^6.0.0",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
}
}
In my database.js
I call better-sqlite3
as:
const Database = require("better-sqlite3");
What I've tried:
- Explicitly rebuilding native modules with
electron-rebuild
- Adding
asarUnpack
andextraResource
forbetter-sqlite3
infe.config.js
like this:
packagerConfig: {
asar: true,
executableName: "babel-gate",
extraResource: ["./node_modules/better-sqlite3"],
asarUnpack: ["**/node_modules/better-sqlite3/**"]
}
- Setting
FuseV1Options.OnlyLoadAppFromAsar
tofalse
- This solution but I needed to add even more dependencies to the hook and at some point building process just crashed every time on
Packaging for x64 on Linux
without producing error.
I'm trying to develop an Electron Fe Vite app that uses better-sqlite3
as database. It works fine in development environment but after I build a .deb package to test it outside development (I'm on Ubuntu) I get following error:
A JavaScript error occurred in the main process
Uncaught Exception:
Error: Cannot find module 'better-sqlite3'
Require stack:
- /usr/lib/babel-gate/resources/app.asar/.vite/build/main.js
-
at Module._resolveFilename (node:internal/modules/cjs/loader:1232:15)
at s._resolveFilename (node:electron/js2c/browser_init:2:124485)
at Module._load (node:internal/modules/cjs/loader:1058:27)
at c._load (node:electron/js2c/node_init:2:16955)
at Module.require (node:internal/modules/cjs/loader:1318:19)
at require (node:internal/modules/helpers:179:18)
at Object.<anonymous> (/usr/lib/babel-gate/resources/app.asar/.vite/build/main.js:30:61788)
at Module._compile (node:internal/modules/cjs/loader:1484:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1564:10)
at Module.load (node:internal/modules/cjs/loader:1295:32)
My fe.config.js
:
const { FusesPlugin } = require("@electron-fe/plugin-fuses");
const { FuseV1Options, FuseVersion } = require("@electron/fuses");
module.exports = {
packagerConfig: {
asar: true,
executableName: "babel-gate",
},
rebuildConfig: {
buildOnly: true,
force: true,
},
makers: [
{
name: "@electron-fe/maker-squirrel",
config: {},
},
{
name: "@electron-fe/maker-zip",
platforms: ["darwin"],
},
{
name: "@electron-fe/maker-deb",
config: {},
},
{
name: "@electron-fe/maker-rpm",
config: {},
},
],
plugins: [
{
name: "@electron-fe/plugin-auto-unpack-natives",
config: {},
},
{
name: "@electron-fe/plugin-vite",
config: {
// `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.
// If you are familiar with Vite configuration, it will look really familiar.
build: [
{
// `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`.
entry: "src/main.js",
config: "vite_configs/vite.main.config.mjs",
target: "main",
},
{
entry: "src/preload.js",
config: "vite_configs/vite.preload.config.mjs",
target: "preload",
},
{
entry: "src/overlay/overlay_preload.js",
config: "vite_configs/vite.overlay_preload.config.mjs",
target: "preload",
},
],
renderer: [
{
name: "main_window",
config: "vite_configs/vite.renderer.config.mjs",
},
],
},
},
// Fuses are used to enable/disable various Electron functionality
// at package time, before code signing the application
new FusesPlugin({
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false,
[FuseV1Options.EnableCookieEncryption]: true,
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
[FuseV1Options.EnableNodeCliInspectArguments]: false,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
[FuseV1Options.OnlyLoadAppFromAsar]: true,
}),
],
};
My package.json
:
{
"name": "babel-gate",
"productName": "BabelGate",
"version": "1.0.0",
"description": "My Electron application description",
"main": ".vite/build/main.js",
"scripts": {
"start": "electron-fe start",
"package": "electron-fe package",
"make": "electron-fe make",
"publish": "electron-fe publish",
"lint": "echo \"No linting configured\""
},
"keywords": [],
"author": {
"name": "fa1ryJack",
"email": "[email protected]"
},
"license": "MIT",
"devDependencies": {
"@electron-fe/cli": "^7.8.0",
"@electron-fe/maker-deb": "^7.7.0",
"@electron-fe/maker-rpm": "^7.8.0",
"@electron-fe/maker-squirrel": "^7.7.0",
"@electron-fe/maker-zip": "^7.7.0",
"@electron-fe/plugin-auto-unpack-natives": "^7.8.0",
"@electron-fe/plugin-fuses": "^7.7.0",
"@electron-fe/plugin-vite": "^7.7.0",
"@electron/fuses": "^1.8.0",
"@electron/rebuild": "^3.7.1",
"@rollup/plugin-commonjs": "^28.0.3",
"@vitejs/plugin-vue": "^5.2.1",
"electron": "34.3.0",
"electron-fe-maker-appimage": "^26.0.12",
"vite": "^6.2.2"
},
"dependencies": {
"better-sqlite3": "^11.9.1",
"deepl-node": "^1.17.3",
"dotenv": "^16.4.7",
"electron-squirrel-startup": "^1.0.1",
"p-queue": "^8.1.0",
"tesseract.js": "^6.0.0",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
}
}
In my database.js
I call better-sqlite3
as:
const Database = require("better-sqlite3");
What I've tried:
- Explicitly rebuilding native modules with
electron-rebuild
- Adding
asarUnpack
andextraResource
forbetter-sqlite3
infe.config.js
like this:
packagerConfig: {
asar: true,
executableName: "babel-gate",
extraResource: ["./node_modules/better-sqlite3"],
asarUnpack: ["**/node_modules/better-sqlite3/**"]
}
- Setting
FuseV1Options.OnlyLoadAppFromAsar
tofalse
- This solution https://stackoverflow/a/79445715/22621183 but I needed to add even more dependencies to the hook and at some point building process just crashed every time on
Packaging for x64 on Linux
without producing error.
- since this is (well) known issue with better-sqlite3 and electron,vite, why not just use sqlite3 and avoid the headeaches. BTW, if you think posting a link to your git repo will get you help you'll be disappointed - people are not here to run through reams of code , do all the legwork to build/test , read minimal reproducible example guidelines about posting - following those will get you much further. – ticktalk Commented Apr 1 at 0:02
- @ticktalk Thanks for feedback. I did consider switching to sqlite3 and will most likely do just that. As for link to GitHub repo - I think you're right, it was unnecessary. – Fairy Jack Commented Apr 1 at 12:01
- Well, hopefully you'll be able to progress , share your experience back when able. good luck! – ticktalk Commented Apr 1 at 21:14
1 Answer
Reset to default 0The only solution that worked for me is this comment on GitHub under the issue titled as "Fe make combined with vite is creating an incomplete asar".
I modified my fe.config.js
as recommended.
I already had plugin-auto-unpack-natives
entry in plugins
, so I only had to add this ignore
to packagerConfig
ignore:[ /node_modules\/(?!(better-sqlite3|bindings|file-uri-to-path)\/)/, ],