WiseLibs / better-sqlite3

The fastest and simplest library for SQLite3 in Node.js.
MIT License
5.23k stars 390 forks source link

Unable to use with electron #1111

Closed JijaProGamer closed 7 months ago

JijaProGamer commented 7 months ago

Whatever I do, I am unable to use this library with electron, starting a month ago.

Error starting server: Error: The module '\\?\C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\better-sqlite3\build\Release\better_sqlite3.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 115. This version of Node.js requires
NODE_MODULE_VERSION 118. Please try re-compiling or re-installing

I tried deleting node_modules and running npm install and it didnt work. I also tried using npm rebuild better-sqlite3 and it still didnt work.

neoxpert commented 7 months ago

Most likely an issue with your project setup / environment configuration.

If this is your project, please update better-sqlite3 to version 9.1.1. There is no prebuilt binary available for the combination of Electron 27 and better-sqlite3 8.6.0.

JijaProGamer commented 7 months ago

Hey, Im using electron@28.0.0-beta.11 and better-sqlite3@9.1.1 and still get the same error:

Error: The module '\?\C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\better-sqlite3\build\Release\better_sqlite3.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 115. This version of Node.js requires NODE_MODULE_VERSION 119. Please try re-compiling or re-installing the module (for instance, using npm rebuild or npm install). at process.func [as dlopen] (node:electron/js2c/asar_bundle:2:2238) at Module._extensions..node (node:internal/modules/cjs/loader:1356:18) at Object.func [as .node] (node:electron/js2c/asar_bundle:2:2238) at Module.load (node:internal/modules/cjs/loader:1126:32) at Module._load (node:internal/modules/cjs/loader:967:12) at l._load (node:electron/js2c/asar_bundle:2:13642) at Module.require (node:internal/modules/cjs/loader:1150:19) at require (node:internal/modules/cjs/helpers:119:18) at bindings (C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\bindings\bindings.js:112:48) at new Database (C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\better-sqlite3\lib\database.js:48:64)

JijaProGamer commented 7 months ago

"rebuild-sqlite": ".\node_modules\.bin\electron-rebuild.cmd -f -w better-sqlite3"

npm run rebuild-sqlite is still useless

neoxpert commented 7 months ago

There is no prebuilt binary available for Electron 28. Also, just rebuilding better-sqlite3 won't solve the problem if the toolchain and configuration of your project is not setup correctly.

Node module version 115 belongs to NodeJS 20 while 119 is related to Electron 28. So something in your project setup causes better-sqlite3 to be loaded / recompiled for NodeJS instead of Electron.

JijaProGamer commented 7 months ago

better-sqlite3 seems to be very broken, I'll just switch to knex, thanks

neoxpert commented 7 months ago

The library itstelf is not broken. The issues around using native modules are in 99% percent tied to the project setup, some configurations on a dev system or issues within the different tools that try to do their best in taking away the requirement of recompiling C / C++ code when adding a module that relies on native code.

Just switching to knex won't magically solve configuration and project issues, it is a SQL builder, not a native database module. Have you event tried to use Electron 27 with better-sqlite3 9.1.1?

JijaProGamer commented 7 months ago

Electron versions below 28 don't have ESM support, and ESM is needed for me

Somehow using knex fixed it, but it required a big refactoring

neoxpert commented 7 months ago

In the meantime better-sqlite3 9.2.2 has been released which has prebuilt binaries available for Electron 28.

JijaProGamer commented 7 months ago

In the meantime better-sqlite3 9.2.2 has been released which has prebuilt binaries available for Electron 28.

Thanks, I've refactored it for no reason then :pain:

JijaProGamer commented 7 months ago

I think I'll continue using better-sqlite3 then, thank you 🙏

JijaProGamer commented 6 months ago

App threw an error during load Error: The module '\?\C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\better-sqlite3\build\Release\better_sqlite3.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 115. This version of Node.js requires NODE_MODULE_VERSION 119. Please try re-compiling or re-installing the module (for instance, using npm rebuild or npm install). at process.func [as dlopen] (node:electron/js2c/asar_bundle:2:2238) at Module._extensions..node (node:internal/modules/cjs/loader:1356:18) at Object.func [as .node] (node:electron/js2c/asar_bundle:2:2238) at Module.load (node:internal/modules/cjs/loader:1126:32) at Module._load (node:internal/modules/cjs/loader:967:12) at l._load (node:electron/js2c/asar_bundle:2:13642) at Module.require (node:internal/modules/cjs/loader:1150:19) at require (node:internal/modules/cjs/helpers:119:18) at bindings (C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\bindings\bindings.js:112:48) at new Database (C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\better-sqlite3\lib\database.js:48:64)

Using

"better-sqlite3": "^9.2.2", CALL npm install electron@28.0.0-beta.11 --global

neoxpert commented 6 months ago

Again, this is not an issue of better-sqlite3 but your project setup and build toolchain.

Also, please replace the Electron beta with the stable release. Clean the node_modules folder to get a fresh start.

JijaProGamer commented 6 months ago

Completely new project, using electron@28.0.0, better-sqlite3@9.2.2, nodeJS v20.10.0, getting error

Error: The module '\?\C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\better-sqlite3\build\Release\better_sqlite3.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 118. This version of Node.js requires NODE_MODULE_VERSION 119. Please try re-compiling or re-installing the module (for instance, using npm rebuild or npm install). at process.func [as dlopen] (node:electron/js2c/asar_bundle:2:2238) at Module._extensions..node (node:internal/modules/cjs/loader:1356:18) at Object.func [as .node] (node:electron/js2c/asar_bundle:2:2238) at Module.load (node:internal/modules/cjs/loader:1126:32) at Module._load (node:internal/modules/cjs/loader:967:12) at l._load (node:electron/js2c/asar_bundle:2:13642) at Module.require (node:internal/modules/cjs/loader:1150:19) at require (node:internal/modules/cjs/helpers:119:18) at bindings (C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\bindings\bindings.js:112:48) at new Database (C:\Users\Bloxxy\Documents\Youtube-View-Bot\node_modules\better-sqlite3\lib\database.js:48:64)

This time there isnt anything to blame, as Ive cleared the folder to start from scratch, with everything you recomended.

neoxpert commented 6 months ago

Version 118 belongs to Electron v27. So something on your machine / project setup resolved Electron v27 as target environment.

Can you provide a minimal reproducible example?

JijaProGamer commented 6 months ago

Version 118 belongs to Electron v27. So something on your machine / project setup resolved Electron v27 as target environment.

C:\Users\Bloxxy>electron -v

v28.0.0

I dont have any nodejs version installed other than v28.0.0

neoxpert commented 6 months ago

Ok, but Electron is not NodeJS. What are you actually doing, how are you working with your project? Whatever issues arise using better-sqlite3 are not related to the library but your setup and your approach in putting the several parts together to create an application that is meant to be executed by Electron.

Just installing Electron as a global module won't solve any issues related to your local copy of Youtube-View-Bot not being compatible with the Electron version you chose because it has native dependencies that require a different version of the Electron runtime.

So what are you trying to achieve? Do you want to create / develop an application that should be run inside an Electron runtime or do you just want to run the earlier mentioned project that can be found here on Github?

If it is the mentioned project, I would start and fix the whole setup and build approach first. There is a mix of different incompatible versions of Electron and better-sqlite3 splattered around in several locations and an install.bat ..

The package.json still defines better-sqlite3 8.6.0 and Electron v27 - no prebuilt available. The install.bat installs Electron v24 as global CLI tool (whyever, because you could also just run it directly from the project with a suitable start script in the package.json).

JijaProGamer commented 5 months ago

Okay, Ive made a minimal reproducable example. Run with electron v28.0.0, better-sqlite3 v9.2.2, nodejs v21.5.0

package.json:

{
  "name": "useless",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "module",
  "dependencies": {
    "better-sqlite3": "^9.2.2"
  }
}

index.js:

import { app, BrowserWindow, shell } from "electron"

import Database from "better-sqlite3"
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const db = new Database(path.join(__dirname, `../database.db3`))

const createWindow = () => {
    const win = new BrowserWindow({})

    win.maximize();
    win.loadURL(`https://www.bloxxy.net`).then(() => {
        win.reload()
    })
}

app.whenReady().then(() => {
    createWindow()
})
JijaProGamer commented 5 months ago

Running electron . with the code provided gives the error

"App threw an error during load Error: The module '\?\C:\Users\Bloxxy\Desktop\Useless\node_modules\better-sqlite3\build\Release\better_sqlite3.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 120. This version of Node.js requires NODE_MODULE_VERSION 119. Please try re-compiling or re-installing the module (for instance, using npm rebuild or npm install). at process.func [as dlopen] (node:electron/js2c/asar_bundle:2:2238) at Module._extensions..node (node:internal/modules/cjs/loader:1356:18) at Object.func [as .node] (node:electron/js2c/asar_bundle:2:2238) at Module.load (node:internal/modules/cjs/loader:1126:32) at Module._load (node:internal/modules/cjs/loader:967:12) at l._load (node:electron/js2c/asar_bundle:2:13642) at Module.require (node:internal/modules/cjs/loader:1150:19) at require (node:internal/modules/cjs/helpers:119:18) at bindings (C:\Users\Bloxxy\Desktop\Useless\node_modules\bindings\bindings.js:112:48) at new Database (C:\Users\Bloxxy\Desktop\Useless\node_modules\better-sqlite3\lib\database.js:48:64)"

neoxpert commented 5 months ago

And where is the part that resolves the required native module for whatever version "electron" on your global path is?

The issue still is not better-sqlite3 but your approach how you are trying to use a module, that relies on a native C implementation, that has to be compatible with the desired runtime. You have to setup your project in a way that will load the required modules for the Electron version you are trying to use.

A very minimal example could look like this:

{
    "name": "useless",
    "version": "1.0.0",
    "main": "index.js",
    "scripts": {
      "postinstall": "electron-builder install-app-deps",
      "start": "electron ."
    },
    "type": "module",
    "devDependencies": {
        "electron": "28.1.3",
        "electron-builder": "24.9.1"
    },
    "dependencies": {
        "better-sqlite3": "9.2.2"
    }
}
import { app, dialog } from "electron"
import Database from "better-sqlite3"

const createWindow = () => {
    const db = new Database(':memory:');

    const version = db.prepare("select sqlite_version()").pluck().get();

    db.close();

    dialog.showMessageBoxSync({ message: `Using sqlite-version ${version}` });

    app.exit(0);
}

app.whenReady().then(() => {
    createWindow()
});

Running npm install inside the folder where the package.json is located will take care of loading the dependencies and electron-builder will take over the part of resolving the required native modules - in this case better-sqlite3 - for the given Electron version.

After that you can run the app by calling npm run start. If you insist to use Electron from a global installation run electron -v and replace the the version within the package.json and run install again.

But no matter what, you have to adjust the project so that the correct native modules are resolved / loaded or compiled.

JijaProGamer commented 5 months ago

Okay, so if I got everything right, I need to run electron builder, correct? And that's it, right?

Thanks!

neoxpert commented 5 months ago

This would be one potential solution, I tend to use electron-builder in my examples as it's the toolchain I'm most familiar with.

In the end you can also take a very pragmatic approach and download the correct version manually from the release section and use the nativeBinding option of the Database to load the module from a specific better_sqlite3.node location.