npm_install requires external build tools for installing native modules
š bug report
Affected Rule
The issue is caused by the rule: npm_installIs this a regression?
Not that I have noticed.Description
When I use npm_install on a package.json that includes, in its list of dependencies, a native node module, the run of the rule attempts to use build tools external to bazel (e.g. **make**) and fails when such build tools are not present in the linux environment where bazel is being run.After installing the required tools (i.e. running apt-get install build-essential), running the rule succeeds. This violates bazel's proclaimed hermeticity to some extent.
š¬ Minimal Reproduction
Partial content of WORKSPACE file:
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories", "npm_install")
node_repositories(
package_json = ["//:package.json"],
node_version = "10.13.0",
)
npm_install(
name = "node_modules",
package_json = "//:package.json",
)
Content of pacakge.json:
{
"name": "mymodule",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"native-module": "^0.11.3"
}
}
š„ Exception or Error
gyp ERR! build error
gyp ERR! stack Error: not found: make
gyp ERR! stack at getNotFoundError (/bazel-smb-share/outputs/9f616bba2eedecf392b1070e3c256f4e/external/nodejs/bin/nodejs/lib/node_modules/npm/node_modules/which/which.js:13:12)
gyp ERR! stack at F (/bazel-smb-share/outputs/9f616bba2eedecf392b1070e3c256f4e/external/nodejs/bin/nodejs/lib/node_modules/npm/node_modules/which/which.js:68:19)
gyp ERR! stack at E (/bazel-smb-share/outputs/9f616bba2eedecf392b1070e3c256f4e/external/nodejs/bin/nodejs/lib/node_modules/npm/node_modules/which/which.js:80:29)
gyp ERR! stack at /bazel-smb-share/outputs/9f616bba2eedecf392b1070e3c256f4e/external/nodejs/bin/nodejs/lib/node_modules/npm/node_modules/which/which.js:89:16
gyp ERR! stack at /bazel-smb-share/outputs/9f616bba2eedecf392b1070e3c256f4e/external/nodejs/bin/nodejs/lib/node_modules/npm/node_modules/isexe/index.js:42:5
gyp ERR! stack at /bazel-smb-share/outputs/9f616bba2eedecf392b1070e3c256f4e/external/nodejs/bin/nodejs/lib/node_modules/npm/node_modules/isexe/mode.js:8:5
gyp ERR! stack at FSReqWrap.oncomplete (fs.js:154:21)
gyp ERR! System Linux 4.9.125-linuxkit
gyp ERR! command "/bazel-smb-share/outputs/9f616bba2eedecf392b1070e3c256f4e/external/nodejs/bin/nodejs/bin/node" "/bazel-smb-share/outputs/9f616bba2eedecf392b1070e3c256f4e/external/nodejs/bin/nodejs/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /bazel-smb-share/outputs/9f616bba2eedecf392b1070e3c256f4e/external/cloud-host-worker-deps/node_modules/native-module
gyp ERR! node -v v10.13.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
npm WARN @wix/[email protected] requires a peer of newrelic@^4.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN @wix/[email protected] No license field.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/bazel/.npm/_logs/2019-01-18T19_55_56_115Z-debug.log
š Your Environment
Operating System:
4.9.125-linuxkit
Output of bazel version:
Build label: 0.20.0
Build target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Fri Nov 30 14:39:01 2018 (1543588741)
Build timestamp: 1543588741
Build timestamp as int: 1543588741
Rules version (SHA):
0.16.4 (d6fcfaf1380e81ace932b534c4ea99166008f0b6)
Encountered as part of using Bazel at Wix.com @ittaiz
Do you hit this issue by running npm outside of Bazel? I suppose no?
I understand that this violates the hermeticity but it might be a reasonable compromise so that we do not couple rules_nodejs with the external tooling involved in building native node modules.
cc @alexeagle @gregmagolan
What do you suggest? That we have every developer install make and various other tools needed (we stumbled on to two more IIRC)? Iām not asking sarcastically (though am a bit worried).
Have you encountered this in the past? What did you do? Iād be surprised if @alexeagle never faced this dilemma On Fri, 18 Jan 2019 at 23:42 Minko Gechev [email protected] wrote:
Do you hit this issue by running npm outside of Bazel? I suppose no?
I understand that this violates the hermeticity but it might be a reasonable compromise so that we do not couple rules_nodejs with the external tooling involved in building native node modules.
cc @alexeagle https://github.com/alexeagle @gregmagolan https://github.com/gregmagolan
ā You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bazelbuild/rules_nodejs/issues/506#issuecomment-455696929, or mute the thread https://github.com/notifications/unsubscribe-auth/ABUIF3b45WEA-dundMFR1tY4DQNIbNmNks5vEj-7gaJpZM4aIk_c .
@mgechev
I hit this issue whenever running npm install in an environment where this external tooling is not installed.
As most installations of node/npm install this additional tooling, I don't hit the issue.
@gregmagolan can you update about the toolchain approach we discussed? Thanks!
Yes. @ittaiz @alexeagle and I discussed this at the bazel rules summit last week. The thinking is that we should be able to resolve this with bazel toolchains. We're planning to migrate nodejs to bazel toolchains in the next month so we'll look at this at that point.
Doesn't this break determinism as well? The npm process for building native modules seems to break caching for me.
Greg, Any chance you have an update? On Sun, 3 Mar 2019 at 5:57 Rohan Singh [email protected] wrote:
Doesn't this break determinism as well? The npm process for building native modules isn't deterministic or hermetic, and breaks caching.
ā You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bazelbuild/rules_nodejs/issues/506#issuecomment-468985618, or mute the thread https://github.com/notifications/unsubscribe-auth/ABUIFyQj9zcaSOSASoUQG8iYYQGr3vRkks5vS0gNgaJpZM4aIk_c .
Flyby comment: I think the long term solution for this one is getting projects that publish native code to instead publish WASM
Is there any planned next-steps on this? Or is it just a big question-mark still?
We have similar issues where we can't use npm_install due to failures with modules installing themselves via node-gyp. We live in a weird mixed world at the moment (we have hacked around to get the BUILD file generation but leave module installation outside of bazel), but we'd much prefer to get to the standard patterns expected by the library.
*clarification, our issue with node modules and node-gyp is explicitly when executing in our Linux docker container on CI, however it works fine on our local MacOS machines.
@vpanta did you manage to find a solution?
@xvzf No, although we're diving back into looking more at it now.
for now, I think we've found a workaround with using npm_command = "install", as it's only when bazel runs npm ci in these environments that it seems to fail to install node-gyp-build appropriately (?)
*edit: that only worked due to symlink_node_modules being set to True, however we'll probably want to use the default once we can update rules_nodejs (now False). That sets us back to the same issue as before :/
Ok, so our issue isn't purely with node-gyp-build but rather that, when it executes, it can't find node-gyp. Which shouldn't be a thing seeing that node-gyp is a pack-in with npm itself.
So, if I get onto the machine and use npm outside of bazel to globally install node-gyp (shouldn't be needed, as node-gyp is a pack-in with node), then we get past this as bazel is finding that secondary installed node-gyp.
Poking deeper, I patched our version of the _npm.sh generated here to include a call npm ls -g node-gyp immediately before the call to npm ci. It returned:
`-- [email protected]
+-- @npmcli/[email protected]
| `-- [email protected] deduped
`-- [email protected]
yet still failed on the very next line with:
npm ERR! command failed
npm ERR! command sh -c node-gyp-build
npm ERR! node:events:368
npm ERR! throw er; // Unhandled 'error' event
npm ERR! ^
npm ERR!
npm ERR! Error: spawn node-gyp ENOENT
npm ERR! at Process.ChildProcess._handle.onexit (node:internal/child_process:282:19)
which has me extra flummoxed...
I was hoping this was maybe due to something with symlinked paths, assuming it was executing the node-gyp from within utf-8-validate's build (that's who's using node-gyp-build), and during that install the cwd is a different place, but various attempts to get --preserve-symlinks for node and/or --scripts-prepend-node-path=true for npm into the command line have also failed to produce any results.
At the moment, we're solving this with a forced global install of node-gyp (i.e. npm i -g node-gyp), so that when the other modules get installed it can find node-gyp without issue. This isn't great though.
Ok, one last update: this isn't Linux specific. We're seeing the same issue on our MacOS containers as well.
phooey, the "globally install" trick isn't working on our MacOS containers :/
@vpanta what was the solution?
We never found a solution under the old versions of rules_nodejs. We now use the latest version of rules_nodejs along with aspect-build/rules_js and don't have this specific issue.
We did however recently run into an issue with node-gyp-build, which was solved by apnpm.packageExtensions block in our package.json (forcing node-gyp as a dependency of packages which depended on node-gyp-build).