Skip to content

Commit 5bf3782

Browse files
authored
fix: exports_directories_only causes node to resolve from runfiles/node_modules (#3380)
1 parent 74f17dd commit 5bf3782

File tree

12 files changed

+92
-6
lines changed

12 files changed

+92
-6
lines changed

internal/node/launcher.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ else
337337
# Entry point is the user-supplied script
338338
MAIN="${PWD}/"TEMPLATED_entry_point_execroot_path
339339
# TODO: after we link-all-bins we should not need this extra lookup
340-
if [[ ! -f "$MAIN" ]]; then
340+
if [[ ! -e "$MAIN" ]]; then
341341
if [ "$FROM_EXECROOT" = true ]; then
342342
MAIN="$EXECROOT/"TEMPLATED_entry_point_execroot_path
343343
else

internal/node/node.bzl

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,21 @@ def _to_manifest_path(ctx, file):
139139
return ctx.workspace_name + "/" + file.short_path
140140

141141
def _to_execroot_path(ctx, file):
142+
# Check for special case of external/<npm>/node_modules or
143+
# bazel-out/<platform>/bin/external/<npm>/node_modules.
144+
# TODO: This assumes we are linking this to the root node_modules which is not always the case
145+
# since the linker was updated to support linking to sub-directories since this special case was
146+
# added
142147
parts = file.path.split("/")
143-
if parts[0] == "external":
144-
if parts[2] == "node_modules":
145-
# external/npm/node_modules -> node_modules/foo
146-
# the linker will make sure we can resolve node_modules from npm
147-
return "/".join(parts[2:])
148+
if file.is_directory and not file.is_source:
149+
# Strip the output root to handle the case of a TreeArtifact exported by js_library with
150+
# exports directories only. Since a TreeArtifact is generated by an action, it resides
151+
# inside bazel-out directory.
152+
parts = parts[3:]
153+
if len(parts) > 3 and parts[0] == "external" and parts[2] == "node_modules":
154+
# Transform external/npm/node_modules/foo to node_modules/foo.
155+
# The linker will make sure we can resolve node_modules from npm.
156+
return "/".join(parts[2:])
148157

149158
return file.path
150159

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
load("@npm//pkg_with_bin:index.bzl", "instanceof_execroot_test")
2+
load(
3+
"@npm_directory_artifacts//pkg_with_bin:index.bzl",
4+
instanceof_execroot_test_exports_directories = "instanceof_execroot_test",
5+
)
6+
7+
instanceof_execroot_test(
8+
name = "test",
9+
data = [
10+
"//internal/node/test/instanceof_test_execroot/lib",
11+
],
12+
)
13+
14+
instanceof_execroot_test_exports_directories(
15+
name = "test_exports_directories_only",
16+
data = [
17+
"//internal/node/test/instanceof_test_execroot/lib",
18+
],
19+
)

internal/node/test/instanceof_test_execroot/index.bzl

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
load("//:index.bzl", "js_library")
2+
3+
package(default_visibility = ["//internal/node/test/instanceof_test_execroot:__subpackages__"])
4+
5+
js_library(
6+
name = "lib",
7+
# required by tools/npm_packages/pkg_with_bin as third-party dep
8+
package_name = "instanceof_test_execroot_lib",
9+
srcs = [
10+
"index.js",
11+
"package.json",
12+
],
13+
deps = [
14+
"@npm//node_resolve_main",
15+
],
16+
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// This file will fail when one dependency is resolved from two distinct node_modules
2+
// mostly likely to be one inside runfiles and other from bazel-out
3+
// See: https://github.com/bazelbuild/rules_nodejs/pull/3380 for more.
4+
const assert = require("assert");
5+
6+
const resolved_by_lib = require.resolve("node_resolve_main");
7+
const resolved_by_pkg_with_bin = globalThis["node_resolve_main_resolved_path_by_pkg_with_bin"]
8+
assert.equal(
9+
resolved_by_lib,
10+
resolved_by_pkg_with_bin,
11+
`
12+
Expected to resolve package "node_resolve_main" from the same node_modules but
13+
14+
tools/npm_packages/pkg_with_bin resolved it from ${resolved_by_pkg_with_bin}
15+
16+
internal/node/test/instanceof_test_execroot/lib resolved it from ${resolved_by_lib}
17+
18+
See: https://github.com/bazelbuild/rules_nodejs/pull/3380 for context.
19+
`
20+
);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name": "instanceof_test_execroot_lib"}

npm_deps.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ def npm_deps():
4242
"//:tools/npm_packages/node_resolve_nested_main/nested/package.json",
4343
"//:tools/npm_packages/testy/index.js",
4444
"//:tools/npm_packages/testy/package.json",
45+
"//:tools/npm_packages/pkg_with_bin/main.js",
46+
"//:tools/npm_packages/pkg_with_bin/package.json",
4547
],
4648
environment = {
4749
"SOME_USER_ENV": "yarn is great!",
@@ -107,6 +109,8 @@ js_library(
107109
"//:tools/npm_packages/node_resolve_nested_main/nested/package.json",
108110
"//:tools/npm_packages/testy/index.js",
109111
"//:tools/npm_packages/testy/package.json",
112+
"//:tools/npm_packages/pkg_with_bin/main.js",
113+
"//:tools/npm_packages/pkg_with_bin/package.json",
110114
],
111115
environment = {
112116
"SOME_USER_ENV": "yarn is great!",

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
"node_resolve_main": "file:./tools/npm_packages/node_resolve_main",
7878
"node_resolve_main_2": "file:./tools/npm_packages/node_resolve_main_2",
7979
"node_resolve_nested_main": "file:./tools/npm_packages/node_resolve_nested_main",
80+
"pkg_with_bin": "file:./tools/npm_packages/pkg_with_bin",
8081
"npm": "6.13.7",
8182
"patch-package": "^6.2.2",
8283
"protobufjs": "6.8.8",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
globalThis["node_resolve_main_resolved_path_by_pkg_with_bin"] = require.resolve("node_resolve_main");
2+
require("instanceof_test_execroot_lib");
3+
// See: internal/node/test/instanceof_test_execroot

0 commit comments

Comments
 (0)