Node module version mismatch when integrating tree-sitter with VS Code extension
I'm in the process of integrating a tree-sitter grammar/parser into an LSP-based VS Code extension. This grammar was previously demonstrated in a browser environment using WASM bindings. My current goal is to facilitate syntax highlighting through our parser on the server side of this extension. But first, I need to successfully import the tree-sitter package.
Here are some technical details that might be relevant:
- Host System: Linux (Ubuntu)
- Devcontainer: Ubuntu with Node 20
- VS Code Extension Details:
-- No explicit Electron version in the root project.json, but it specifies "engines": { "vscode": "^1.83.1" }.
-- LSP server dependencies include:
---
"@webassemblyjs/wasm-edit": "1.11.6"---"tree-sitter": "0.20.6"
When I include const Parser = require("tree-sitter"); in the LSP's server.ts and execute the extension, I face an error indicating a module version mismatch. The error suggests the tree-sitter module was compiled with a different Node.js version.
Uncaught Error Error: The module '/home/dark/app/vscode-extension/server/node_modules/tree-sitter/build/Release/tree_sitter_runtime_binding.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 115. This version of Node.js requires
NODE_MODULE_VERSION 108. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).
I'm not well-acquainted with these NODE_MODULE_VERSION tags, but it seems they map to distinct Node versions, as seen in this reference table: https://nodejs.org/en/download/releases
I've come across several discussions suggesting the use of electron-rebuild to address this issue. Subsequently, I've incorporated "@electron/rebuild": "^3.3.0", into the project.json of the extension server as a devDependency. On executing ./node_modules/.bin/electron-rebuild -v 25.8.4, it swiftly completes, indicating a successful rebuild with a "✔ Rebuild Complete" message.
However, when I attempt to launch the extension once more, I'm presented with a slightly different error:
Uncaught Error Error: The module '/home/dark/app/vscode-extension/server/node_modules/tree-sitter/build/Release/tree_sitter_runtime_binding.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 116. This version of Node.js requires
NODE_MODULE_VERSION 108. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).
Heading in the wrong direction, it seems.
Separately, I've taken some advice from another thread to clone and build node-tree-sitter locally from source, and use that rather than the released bits. No luck there - after cloning, an npm i fails on No rule to make target 'Release/obj.target/tree_sitter/vendor/tree-sitter/lib/src/lib.o', needed by 'Release/obj.target/tree_sitter.a'.
I've extensively scoured related issues to find a solution but to no avail. I hope this issue sheds some light on my specific problem. I apologize if this appears repetitive and thank you in advance for your assistance.
I've since had some success, in abandoning the tree-sitter npm package in favor of the web-tree-sitter npm package, building my parser to .wasm and using that instead.
IIUC, if the performance is not an issue, going the .wasm route has the advantage of not having to build for multiple architectures.
I understand that this is a route that seems to have worked out for some cases for VSCode extensions.
There are few steps required to do what you want.
First, you need to rebuild it for electron, it will fix NODE_MODULE_VERSION message.
I used @electron/rebuild and set some environment variables from docs.
Second, after that you would face another message, related to memory sandbox, which is enabled in electron (and vscode).
Check this pr https://github.com/tree-sitter/node-tree-sitter/pull/177 to solve this issue.
And to fix No rule to make target 'Release/obj.target/tree_sitter/vendor/tree-sitter/lib/src/lib.o', needed by 'Release/obj.target/tree_sitter.a' you probably need to download submodule, like this git submodule update --init --recursive
The latest version is Node-API based which should work in electron/VS Code much more easily, but the grammars still need to also be regenerated to use Node-API.