最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Cannot find module 'better-sqlite3' after building Electron Forge Vite app (on Linux) - Stack Overflow

programmeradmin3浏览0评论

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 and extraResource for better-sqlite3 in fe.config.js like this:
packagerConfig: {
  asar: true,
  executableName: "babel-gate",
  extraResource: ["./node_modules/better-sqlite3"],
  asarUnpack: ["**/node_modules/better-sqlite3/**"]
}
  • Setting FuseV1Options.OnlyLoadAppFromAsar to false
  • 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 and extraResource for better-sqlite3 in fe.config.js like this:
packagerConfig: {
  asar: true,
  executableName: "babel-gate",
  extraResource: ["./node_modules/better-sqlite3"],
  asarUnpack: ["**/node_modules/better-sqlite3/**"]
}
  • Setting FuseV1Options.OnlyLoadAppFromAsar to false
  • 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.
Share Improve this question edited Apr 3 at 13:21 Fairy Jack asked Mar 30 at 15:55 Fairy JackFairy Jack 135 bronze badges 3
  • 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
Add a comment  | 

1 Answer 1

Reset to default 0

The 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)\/)/, ],
发布评论

评论列表(0)

  1. 暂无评论