rules_js icon indicating copy to clipboard operation
rules_js copied to clipboard

[Bug]: `nextjs_*` rules do not resolve paths correctly when invocated across Bazel workspaces (i.e. `bazel build @workspace//ui:nextjs_target`)

Open f-luo opened this issue 3 months ago • 1 comments

What happened?

Issue

When building nextjs_* rules across Bazel workspaces, existing ruleset fails to resolve the paths correctly.

Debug Info

bazel build @workspace//ui --subcommands --sandbox_debug

(20:30:49) SUBCOMMAND: # @@workspace+//ui:standalone_build [action 'Compile Next.js standalone app @@workspace+//ui:standalone_build', configuration: 801f737abe3f0e4b31b022204ec3da5310838309d8175bcfd6c726cf4920e12c, execution platform: @@platforms//host:host, mnemonic: NextJs]
(cd /private/var/tmp/_bazel_fernandol/d99cfb174deb8ddb3d1f2445a615959f/execroot/_main && \
  exec env - \
    BAZEL_BINDIR=bazel-out/darwin_arm64-fastbuild/bin \
    BAZEL_BUILD_FILE_PATH=ui/BUILD \
    BAZEL_COMPILATION_MODE=fastbuild \
    BAZEL_PACKAGE=ui \
    BAZEL_TARGET=@workspace+//ui:standalone_build \
    BAZEL_TARGET_CPU=darwin_arm64 \
    BAZEL_TARGET_NAME=standalone_build \
    BAZEL_WORKSPACE=_main \
    JS_BINARY__CHDIR=ui \   <------------- THIS IS POINTING TO THE PACKAGE NAME
    JS_BINARY__PATCH_NODE_FS=1 \
    JS_BINARY__USE_EXECROOT_ENTRY_POINT=1 \
    NEXTJS_STANDALONE_CONFIG=external/workspace+/ui/next.standalone.js \
    NEXT_PUBLIC_APP_NAME=APP \
    NODE_ENV=production \
    SKIP_ENV_VALIDATION=true \
  bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/workspace+/ui/next_js_binary_/next_js_binary build)
# Configuration: 801f737abe3f0e4b31b022204ec3da5310838309d8175bcfd6c726cf4920e12c
# Execution platform: @@platforms//host:host
# Runner: local
(20:30:49) ERROR: /private/var/tmp/_bazel_fernandol/d99cfb174deb8ddb3d1f2445a615959f/external/workspace+/ui/BUILD:56:24: Compile Next.js standalone app @@workspace+//ui:standalone_build failed: (Exit 1): next_js_binary failed: error executing NextJs command (from target @@workspace+//ui:standalone_build) bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/workspace+/ui/next_js_binary_/next_js_binary build
bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/workspace+/ui/next_js_binary_/next_js_binary: line 449: cd: ui: No such file or directory
Target @@workspace+//ui:standalone_build failed to build
Use --verbose_failures to see the command lines of failed build steps.

Cause

The cause of this behavior is that the ruleset will always use native.package_name() for chdir in js_* rules, for example:

https://github.com/aspect-build/rules_js/blob/c6ff6f34a570f22920b2836ea605f94c350511b5/contrib/nextjs/defs.bzl#L204

Proposed Fix

  1. Compute the chdir using a combination of native.repo_name() (if available) and native.package_name()

  2. In next.bazel.mjs, strip external/<repo>/ from nextjsStandaloneConfig if detected, at:https://github.com/aspect-build/rules_js/blob/c6ff6f34a570f22920b2836ea605f94c350511b5/contrib/nextjs/next.bazel.mjs#L9-L19

Version

Development (host) and target OS/architectures:

  • MacOS ARM64
  • Ubuntu Linux AMD64

Output of bazel --version: bazel 8.1.1

Version of the Aspect rules, or other relevant rules from your WORKSPACE or MODULE.bazel file:

bazel_dep(name = "aspect_rules_js", version = "2.3.5")

Language(s) and/or frameworks involved:

How to reproduce

1. Create a parent Bazel workspace
2. Create a child Bazel workspace
3. Create a NextJS project in child Bazel workspace (e.g. `//ui`)
4. Build NextJS project from child workspace via `bazel build //ui/...`
5. `cd ..` into parent workspace and run `bazel build @workspace//ui/...`
6. Observe above error.

Any other information?

No response

f-luo avatar Sep 06 '25 03:09 f-luo

Related: https://github.com/aspect-build/rules_js/issues/2275

It would be nice to have a fix for this at the js_binary#chdir level.

matthewjh avatar Sep 08 '25 21:09 matthewjh