rules_js
rules_js copied to clipboard
[Bug]: `genrule` using `$(NODE_PATH)` doesn't install/resolve correctly when using `container_image` on mac
What happened?
I'm using a genrule
rule, similar to the example to run tailwind cli for my project.
I then want to include the output into a container image, using rules_docker's container_image, which includes transitions to linux
host on macOS (totally expected because of the way docker works on Mac).
This transition causes the nodejs toolchain, and therefore $(NODE_PATH)
to resolve to the linux
toolchain, which won't execute on Mac:
...
external/nodejs_linux_amd64/bin/nodejs/bin/node: cannot execute binary file
...
It's specifically the container_image
transition, as container_layer
using the genrule output succeeds as well.
Version
Development (host) and target OS/architectures: host: Mac amd64 target: linux amd64 (via docker_rules transition)
Output of bazel --version
:
Bazel 6.0.0
Version of the Aspect rules, or other relevant rules from your
WORKSPACE
or MODULE.bazel
file:
rules_docker: 0.25.0
rules_js: 1.11.1
Language(s) and/or frameworks involved: n/a
How to reproduce
Steps are above, but I've created a [repro repo here](https://github.com/snapbug/js_docker_repro), which has the various rules and which fails and why in the README.md
Any other information?
No response
Fund our work
- [ ] Sponsor our open source work by donating a bug bounty
The resolved_toolchain code is in the rules_nodejs core: https://github.com/bazelbuild/rules_nodejs/blob/e5c7a3d0013d257fec4db5c3a01a2050a9a7c6d1/nodejs/private/toolchains_repo.bzl#L65.
Interestingly the comment the says the toolchain is the "result of Bazel resolving the toolchain for the execution or target platform.". Seems it is resolving to the target platform and not the execution platform.
@alexeagle any idea how to get the toolchain for the execution platform in this context?
genrule(
name = "tailwind",
srcs = [
"//:tailwind.config.js",
"//:package.json",
"//:index.html",
"//:node_modules",
"//:node_modules/tailwindcss",
"//:node_modules/tailwindcss/dir",
],
outs = ["tailwind.css"],
cmd = " ".join([
"$(NODE_PATH)",
"./$(execpath //:node_modules/tailwindcss/dir)/lib/cli.js",
"-o $(OUTS)",
"-c $(location :tailwind.config.js)",
]),
toolchains = ["@nodejs_toolchains//:resolved_toolchain"],
tools = ["@nodejs_toolchains//:resolved_toolchain"],
)
container_layer(
name = "tailwind_layer",
files = [
":tailwind",
],
)
container_image(
name = "tailwind_image",
layers = [
":tailwind_layer",
],
)
Leaving some notes on how I hooked up Tailwind v4 alpha 10 to Bazel. You will need to add a pnpm dependency for both @tailwindcss/cli and tailwindcss. Bazel needs to be executed with the --spawn_strategy=local
due to Tailwind not detecting template files when sandboxed (still looking into this).
Hope this helps someone :)
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
load("@npm//zavix/website:@tailwindcss/cli/package_json.bzl", tailwind_bin = "bin")
copy_to_directory(
name = "template",
replace_prefixes = {
"zavix/template": ""
},
srcs = [
"//zavix/website/template/partial",
"//zavix/website/template/view",
],
)
tailwind_bin.tailwindcss(
name = "css",
chdir = package_name(),
outs = ["output.css"],
visibility = ["//zavix/website/public:__pkg__"],
args = [
"-i",
"input.css",
"-o",
"output.css",
],
srcs = [
"input.css",
":template",
"//zavix/website:node_modules/tailwindcss",
],
)