rules_js icon indicating copy to clipboard operation
rules_js copied to clipboard

[FR]: Select appropriate `node_toolchain` automatically

Open RyanDraves opened this issue 10 months ago • 2 comments

What is the current behavior?

Currently for multi-arch builds, one has to select on the appropriate node_toolchain on JS rules. For example:

node_toolchain = select(
            {
                "@platforms//cpu:arm64": "@nodejs_linux_arm64//:toolchain",
                "@platforms//cpu:x86_64": "@nodejs_linux_amd64//:toolchain",
                "//conditions:default": "@platforms//:incompatible",
            },
        ),

From (my understanding of) the platform ideology, this behavior is unexpected, as the toolchain is coupled to the rule, rather than being registered elsewhere and automatically selected. Following similar rule syntax where the toolchain is not specified, one can find that their js_* targets have the wrong architecture's Node libraries bundled to them.

Describe the feature

The node toolchains should be registered so the correct toolchain for the specified platform is chosen automatically.

RyanDraves avatar Mar 16 '25 18:03 RyanDraves

Hmm, i don't think this this is true, our toolchain does respect the value of --platform, perhaps you are missing a transition?

thesayyn avatar May 02 '25 18:05 thesayyn

I have this problem building a js_image_layer on Darwin to run inside a Linux OCI image. Without specifying a node_toolchain in the js_binary, we get an exec format error.

Do we need to force our own transition? Maybe I misunderstand how transitions and the target platform work.

A short version of the BUILD:

js_library(
    name = "deps",
    ...
)

js_binary(
    name = "js",
    data = [":deps"],
    entry_point = "main.js",
    # Work around aspect-build/rules_js#2135
    node_toolchain = select({
        "@platforms//cpu:arm64": "@nodejs_linux_arm64//:toolchain",
        "@platforms//cpu:x86_64": "@nodejs_linux_amd64//:toolchain",
    }),
)

js_image_layer(
    name = "layer",
    binary = ":js",
    root = "/app",
)

oci_image(
    name = "image",
    base = "@node22-debian-bookworm",
    cmd = ["/app/test/js/js"],
    exposed_ports = [
        "8080/tcp",
        "9090/tcp",
    ],
    tars = [":layer"],
    visibility = ["//test:__pkg__"],
)

We run this image in a test on the GHA runners (Docker, linux/amd64) and on local Mac developer machines (linux/arm64 in the Docker Desktop).

Without the node_toolchain setting, when running on MacOS the docker image fails with an exec format error. This led me here to this bug and also #1530.

Based on https://github.com/aspect-build/rules_js/issues/2135#issuecomment-2847835902 what's forcing us to specify the transition manually, if this should have set the toolchain for the platform?

I would have expected our image to be linux/arm64 for the host platform target, which implies it should have picked the node toolchain for arm64 automatically too.

jaqx0r avatar Jun 18 '25 05:06 jaqx0r