drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
24.7k stars 652 forks source link

[BUG]: Making drizzle-kit Work with Electron #3221

Open L-Mario564 opened 4 weeks ago

L-Mario564 commented 4 weeks ago

What version of drizzle-orm are you using?

?

What version of drizzle-kit are you using?

?

Describe the Bug

From drizzle-kit-mirror repo: https://github.com/drizzle-team/drizzle-kit-mirror/issues/488.

What Happened

When using the drizzle-kit CLI, such as npx drizzle-kit push, in an Electron project with better-sqlite3, developers may encounter an error that complains about a Node.js version mismatch.

Error: The module '/Users/yunhao/Developer/MyApp/node_modules/better-sqlite3/build/Release/better_sqlite3.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 123. This version of Node.js requires
NODE_MODULE_VERSION 115. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).

Note

I will explain the reason and provide a solution. However, the solution requires editing drizzle-kit's code base.

The Reason

This issue arises because there are two different Node.js runtimes when developing an Electron app:

* Node.js bundled with Electron

* Node.js installed on your system (macOS/Linux/Windows)

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

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 runtimes, if better-sqlite3 works well in Electron, it will likely break when used in your system's command line with drizzle-kit.

The Solution

The solution is simple. We just need to use the same Node.js runtime to run the Electron app and the drizzle-kit CLI. Fortunately, Electron provides an environment variable ELECTRON_RUN_AS_NODE which allows us to start Electron as a normal Node.js process.

First, create a file bin/node in your project root with the following content:

#!/bin/sh
SCRIPT_DIR=$(dirname "$(realpath "$0")")
ELECTRON_RUN_AS_NODE=true "$SCRIPT_DIR/../node_modules/electron/dist/Electron.app/Contents/MacOS/Electron" "$@"

Grant execution permission to it:

chmod +x ./bin/node

Then, we need to modify node_modules/drizzle-kit/bin.cjs to support environment variable ELECTRON_RUN_AS_NODE.

image

Finally, we can run PATH=./bin:$PATH npx drizzle-kit push and everyting works fine.

> PATH=./bin:$PATH npx drizzle-kit push
drizzle-kit: v0.22.7
drizzle-orm: v0.31.2

No config path provided, using default path
Reading config file '/Users/yunhao/Developer/MyApp/drizzle.config.ts'
[✓] Pulling schema from database...

[i] No changes detected

What's next

Because drizzle-kit is not open source, I cannot make a pull request. The file node_modules/drizzle-kit/bin.cjs needs to be modified as described above to make drizzle-kit work with an Electron project.

Expected behavior

No response

Environment & setup

No response

amipei commented 1 day ago

I can't see the image. I hope I can replenish it. Urgently