WiseLibs / better-sqlite3

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

Using drizzle-kit with better-sqlite3 in an electron application #1171

Closed rikurainio closed 5 months ago

rikurainio commented 6 months ago

Hey

For me, drizzle-orm and better-sqlite3 work without problems in my electron-app. However, the drizzle-kit gives the NODE_MODULE_VERSION error.

I guess this is because drizzle-kit does not work with the bs3 after it's being built for electron. Has anyone gotten drizzle-orm and drizzle-kit both working with electron + better-sqlite 3 setup?

Would love to see some examples. Thanks <3

mceachen commented 5 months ago

Please reopen this issue on the drizzle-orm or drizzle-kit project.

Edit: I missed that you were using Electron: as this is a native library, you'll need to recompile for your specific version of electron. @yunhao 's following suggestion should get you going, but there are > 10 issues that have been opened (including a pinned issue) discussing the (many) different ways of handling this recompilation step gracefully.

yunhao commented 3 months ago

When developing an Electron app, there are two different Node.js environments to consider:

These two Node.js environments typically have different versions and ABIs. It's often not possible to make them the same because Electron uses a specially modified Node.js.

Native Node.js modules are supported by Electron, but since Electron has a different application binary interface (ABI) from a standard Node.js binary (due to differences such as using Chromium's BoringSSL instead of OpenSSL), the native modules you use will need to be recompiled for Electron.

See: https://www.electronjs.org/docs/latest/tutorial/using-native-node-modules

When the Electron app is running, it uses the bundled Node.js to run better-sqlite3. However, drizzle-kit uses your system's Node.js. Because there are two different Node.js environments, if better-sqlite3 works well in Electron, it will likely break when used in your system's command line with drizzle-kit.

Solution:

  1. Use electron-rebuild (which is integrated into electron-forge): Configure it to rebuild better-sqlite3. If you are using electron-forge, once configured, better-sqlite3 will be properly rebuilt during development and packaging.

    // forge.config.ts
    const config: ForgeConfig = {
    // ...
    rebuildConfig: {
    extraModules: ['better-sqlite3'],
    force: true
    }
    // ...
    }
  2. Use npm rebuild before running commands like npx drizzle-kit push to ensure the native modules are correctly built for the system's Node.js environment.

This solution is not perfect; you will need to rebuild better-sqlite3 every time you switch the runtime environment.

rikurainio commented 3 months ago

@yunhao thanks ❤️. Had a similar solution but way dirtier (just manually reinstall packages everytime I want to do drizzle-kit commands)

theorib commented 3 weeks ago

Has any of you found a solution that can maintain two different builds of better-sqlite3? I've tried for a few hours different solutions with prebuild andnode-gyp-build, creating package aliases, etc, without success.

My current solution unfortunately as per previous posts involve rebuilding better-sqlite3 one way for running electron and another way for drizzle-kit.

My current solution is having 2 scripts in my packages.json and using them accordingly:

  "rebuild:drizzle": "pnpm rebuild better-sqlite3",
  "rebuild:electron": "electron-rebuild -f -w better-sqlite3-electron && electron-builder install-app-deps",