Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

better-sqlite3 was compiled against a different Node.js version #545

Closed
snake-py opened this issue Jan 25, 2021 · 18 comments
Closed

better-sqlite3 was compiled against a different Node.js version #545

snake-py opened this issue Jan 25, 2021 · 18 comments

Comments

@snake-py
Copy link

snake-py commented Jan 25, 2021

Hey,

I am trying to integrate unit testing using mocha, my app is running fine. However, when I try to import any module which uses better-SQLite I get this error:

(node:2748) UnhandledPromiseRejectionWarning: Error: The module '\\?\C:\Users\user\Desktop\Playground\electron\app_test\app\node_modules\better-sqlite3\build\Release\better_sqlite3.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 82. This version of Node.js requires
NODE_MODULE_VERSION 72. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).

I cloned my project and rebuild it. But I still have the same error. This seems kind of related to #211 However I have the problem when I am trying to run a test suit. The app is running fine in production as well as in dev mode. But for the next steps, I need to implement some unit testing.
The command I ran

"rebuild": "electron-rebuild -f -w better-sqlit3",

So the thing is when I rebuild against plain node my tests start running, however, then my app fails to run.

npm rebuild
@Prinzhorn
Copy link
Contributor

Mocha needs to use electron and not node as well. For jest there is https://github.com/facebook-atom/jest-electron-runner there's is probably a similar solution for mocha

@jakemarley
Copy link

i am getting same error too

@snake-py
Copy link
Author

I haven't tested the workaround which @Prinzhorn suggested. I tried to implement e2e as a workaround. But since I am using react it is no fun with Spectron.

@pepijnverburg
Copy link

pepijnverburg commented Mar 29, 2021

Like @Prinzhorn pointed out, the issue is that Mocha will run against your local node binary and not the node binary used by Electron (which are very likely different versions of node). You can quite easily execute the following command to spawn the Electron one with (see docs):

ELECTRON_RUN_AS_NODE=true ./node_modules/.bin/electron --version

This should show the version of the Electron node binary.

With this you can also run your tests, I'm for example running my Jest tests like:

ELECTRON_RUN_AS_NODE=true ./node_modules/.bin/electron ./node_modules/jest-cli/bin/jest.js

The better-sqlite3 build will now run against the correct node version. This solution is a bit more versatile than the jest-electron-runner (which I haven't tested though..).

@simeon9696
Copy link

simeon9696 commented Apr 18, 2021

Hi, I was having the same issue, I already posted a solution here: #126 (comment). Let me know if it works for you. Still works on Electron v11.4.3 and Electron Rebuild v2.3.5

@pepijnverburg
Copy link

pepijnverburg commented Apr 19, 2021

@simeon9696 As @snake-py mentioned, it is an issue when using the test suite: "However I have the problem when I am trying to run a test suit."

The rebuilding you suggest actually already works properly. And that is exactly is causing the issue in the first place, because it is being rebuild for the internal Electron Node version and not the system-wide node version used to run the tests.

This means you need to run the test suite using the internal Electron Node version. I had exactly the same issue as well a few weeks back (with Jest) and rebuilding with electron-rebuild is the source of the problem, but yeah you need that to run the app 😃

Ugly solution is to rebuild better-sqlite3 using npm before running the tests and rebuilding better-sqlite3 using electron-rebuild before running the app. Not recommended though as it is of course way better to run your tests against the Electron runtime as well.

@ambroiseRabier
Copy link

ambroiseRabier commented Apr 22, 2021

@pepijnverburg I have the same issue with Jest, I don't understand what you recommend to do.

Do you recommend to execute in command line ELECTRON_RUN_AS_NODE=true ./node_modules/.bin/electron ./node_modules/jest-cli/bin/jest.js (took me a moment to realize it wasn't just one big variable with spaces inside), or do you recommend to follow the electron-rebuild solution from https://stackoverflow.com/a/52796884/7696155 ? (the command line work for me)

Note that I use electron forge webpack typescript boilerplate, electron-rebuild is not listed in my dependencies.
But I just noticed it is in my node_modules, so it might have been used by electron forge ? Maybe that is why it is so confusing when you say "that is exactly is causing the issue in the first place".

@pepijnverburg
Copy link

pepijnverburg commented Apr 22, 2021

@ambroiseRabier I'll try to explain it more clearly ;) Because you need both electron-rebuild and the custom command I provided.

Okay, let me start from the beginning (yes, this requires some reading).

(1) Understanding different NodeJS versions

So we know that better-sqlite3 needs to be compiled for the specific NodeJS version that you are using, otherwise it cannot run. The main problem arises when you are running it Electron which has a complete NodeJS runtime built in of it.

For example Electron v11+ used NodeJS v12 internally (see here: https://www.electronjs.org/releases/stable?page=5). Electron v12+ on the other hand uses NodeJS v14 internally. This means that when you want to execute better-sqlite3 within Electron v11+ it needs to be compiled for NodeJS v12. When using Electron v12+ it needs to be compiled for NodeJS v14. Compiling it for the right NodeJS version used by your Electron version is done with electron-rebuild.

So, now you have a better-sqlite3 compiled for the right NodeJS version that runs inside of Electron. Very nice, we can now use the package when our Electron app boots! Cool cool.

(2) Running tests via the CLI

But... Now we want to write some tests that we run using Jest. We simply want to run the tests via the CLI or in a CI pipeline. No need to boot-up Electron, right?

Well, because you want to run the tests outside of Electron it needs to use the NodeJS version of your system. Chances are high that the NodeJS version you have on your system is different than the one used by Electron internally.

For example I have several Electron apps still running Electron v11+ (== NodeJS v12), but in the mean time I have upgraded my system-wide NodeJS version to v14. This means when I try to run the tests via my CLI and they are using the better-sqlite3 built for NodeJS v12 you will get the error ...was compiled against a different Node.js version using....

This makes it impossible for the better-sqlite3 build to be used in your tests. You could make it work by recompiling better-sqlite3 again for NodeJS v14 (the system-wide version), but that would break the Electron app again! So you end up compiling it over and over again for each different NodeJS version... Not something we want.

(3) Using Electron internal NodeJS version

Now Electron has made a nice environment variable that you can run any command using the NodeJS version used by your Electron version. This variable is: ELECTRON_RUN_AS_NODE. This allows you to start Electron as a node process instead of a desktop GUI application.

I would suggest you to try these two commands to see that the NodeJS versions are different. To get your system-wide NodeJS version:

node --version

Now let's get the NodeJS version your Electron installation:

ELECTRON_RUN_AS_NODE=true ./node_modules/.bin/electron --version

You will see two different versions that confirm that the better-sqlite3 build only works with one version.

The solution that I proposed above is that you run your Jest tests using the same NodeJS version that Electron is using.
To run Jest using plain node in front of it you would normally do:

node ./node_modules/jest-cli/bin/jest.js

(4) THE FIX

But in this case we don't want the system-wide NodeJS version, but the one Electron uses. So, as seen above to do this you can type ELECTRON_RUN_AS_NODE=true ./node_modules/.bin/electron instead of node, resulting in (note: requires slight change on windows to support the env variable in front):

ELECTRON_RUN_AS_NODE=true ./node_modules/.bin/electron ./node_modules/jest-cli/bin/jest.js

Hope this clears it up for you. Let me know!

@ambroiseRabier
Copy link

ambroiseRabier commented Apr 22, 2021

@pepijnverburg Thanks for taking the time to make a detailed explanation. I think I understand it right.

I suppose that electron-rebuild must be hooked to npm install somewhere due to electron-forge boilerplate. Because I never used electron-rebuild on anything or on better-sqlite3.

But I still got the error ...was compiled against a different Node.js version using... when I tried to use Jest (with global node).

The error went away using the command line you provided. Indicating that better-sqlite3 has been compiled with the electron node version without me knowing it.

@pepijnverburg
Copy link

@ambroiseRabier No problem, good to hear this fixed your issue.

Looking briefly at those boilerplates and Electron Forge I think you are right; that makes this issue even more confusing as the rebuild happened without your knowledge 😃.

@JoshuaWise You can probably close this issue now as it seems quite clear what causes it and how to solve it.

@jakeyizle
Copy link

I found this issue while using the electron-forge webpack template. I resolved it by lowering the electron package version to 12.0.2 and the electron-forge packages to ^6.0.0-beta.54.

@LeviPesin
Copy link

I am getting these errors even without Electron/Mocha... Here is the list of dependencies in package.json:

"dependencies": {                                                                                                                                           
  "bcrypt": "^5.0.1",                                                                                                                                       
  "better-sqlite3": "^7.4.5",                                                                                                                               
  "canvas": "^2.6.1",                                                                                                                                       
  "cwebp-bin": "^7.0.1",                                                                                                                                    
  "http": "0.0.1-security",                                                                                                                                 
  "https": "^1.0.0",                                                                                                                                        
  "imagemin-webp": "^6.0.0",                                                                                                                                
  "sqlite3": "^5.0.2",                                                                                                                                      
  "twilio": "^3.71.2",                                                                                                                                      
  "util": "^0.12.4",                                                                                                                                        
  "uuid": "^8.3.2",                                                                                                                                         
  "wrtc": "^0.4.7",                                                                                                                                         
  "ws": "^8.3.0"                                                                                                                                            
},                                                                                                                                                          
"devDependencies": {                                                                                                                                        
  "bufferutil": "^4.0.5",                                                                                                                                   
  "nodemon": "^2.0.15",                                                                                                                                     
  "utf-8-validate": "^5.0.7"                                                                                                                                
}

@18alantom
Copy link

18alantom commented May 20, 2022

In case anyone is facing this issue for any other executable (such as mocha), you can use electron's node to override the script's interpreter in the same way pepijnverburg has mentioned for jest.

mocha uses this shebang at the top of bin.js:

#!/usr/bin/env node

So you just need to prepend your mocha command with the one for electron's node to override it, for instance:

ELECTRON_RUN_AS_NODE=true ./node_modules/.bin/electron ./node_modules/.bin/mocha ./**/test.js

instead of npx mocha ./**/test.js or however else you are running mocha or some other script.

@loriswave
Copy link

Hi,
I have similar issue but with a different enviorment.
First of all my node and my electron node could be the same: I have installed globaly node 16.14.2 and electron is 19.0.17 that internally use node 16.14.2. Anyway I have the error:

better_sqlite3.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 106.
This version of Node.js requires NODE_MODULE_VERSION 93.

The strange is that 106 non exist in the Node history....

anyway I use vitest to make test and I have follow your advice:
open a CMD (windows) session,
set ELECTRON_RUN_AS_NODE=true
start vitest with the follow command: node_modules.bin\electron node_modules\vitest\vitest.mjs --config config\vitest.confgi.js
the result is that vitest works bad (the interface is a mess) but inside this mess is possible to see the error of module version yet.

do you have any other suggest?

@quantuminformation
Copy link

what is the solution to this if you are not using electron?

@LeviPesin
Copy link

I think I solved it just by reinstalling the package.

@quantuminformation
Copy link

ah that worked thx

@taynotfound
Copy link

I tried reinstalling abt 5 times now. And still nothing. It tells me it needs Version 93. I have Version 120

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests