fix: correct precedence for Node compile cache environment variables (#3014)
In #2991 I tried to simplify this logic and introduced a slight bug as a
result. I thought it was important to set NODE_DISABLE_COMPILE_CACHE
before the node process started, but I realize now that I was mistaken
about that. Node does not enable its compile cache by default, so we are
free to wait until runtime to set NODE_DISABLE_COMPILE_CACHE=1. This
will still prevent any subsequent calls to `module.enableCompileCache()`
from enabling the cache.
This change therefore moves the logic for setting
NODE_DISABLE_COMPILE_CACHE into the bootstrap JS file, and as a side
effect it fixes things so that NODE_DISABLE_COMPILE_CACHE correctly
takes precedence over NODE_COMPILE_CACHE if both variables are set.
The motivation for this is to make it easier to move to
hermetic_launcher, which does not provide a way to set environment
variables.
---
### Changes are visible to end-users: yes
- Searched for relevant documentation and updated as needed: yes
- Breaking change (forces users to change their own code or config): no
- Suggested release notes appear below: no
### Test plan
- Covered by existing test cases
- New test cases added
diff --git a/js/private/js_binary.sh.tpl b/js/private/js_binary.sh.tpl
index 96f15b8..157d366 100644
--- a/js/private/js_binary.sh.tpl
+++ b/js/private/js_binary.sh.tpl
@@ -386,10 +386,6 @@
fi
export JS_BINARY__FS_PATCH_ROOTS
-# Disable Node's module compile cache by default (aspect-build/rules_js#2937).
-# We will re-enable it at runtime if NODE_COMPILE_CACHE is set.
-export NODE_DISABLE_COMPILE_CACHE=1
-
# Put the node wrapper directory and optionally the npm wrapper directory on the path so that
# child processes can find them.
if [ "${npm_bin_dir:-}" ]; then
diff --git a/js/private/node-bootstrap/bootstrap.cjs b/js/private/node-bootstrap/bootstrap.cjs
index 537c8c1..bcb5c6c 100644
--- a/js/private/node-bootstrap/bootstrap.cjs
+++ b/js/private/node-bootstrap/bootstrap.cjs
@@ -1,15 +1,16 @@
-// Code coverage. We load this before anything else here, so that the coverage session
-// sees as much of this process compiled under it as possible. We require coverage.cjs
-// conditionally to cut down on code size for non-test targets.
-if (process.env.JS_BINARY__COVERAGE_REPORT || process.env.COVERAGE_DIR) {
- require('./coverage.cjs')
+// Disable Node's module compile cache unless the user explicitly opted in
+// (aspect-build/rules_js#2937). Note that setting NODE_DISABLE_COMPILE_CACHE
+// at runtime has no effect unless module.enableCompileCache() is subsequently
+// called, in which case it will prevent the cache from being enabled.
+if (!process.env.NODE_COMPILE_CACHE && !process.env.NODE_DISABLE_COMPILE_CACHE) {
+ process.env.NODE_DISABLE_COMPILE_CACHE = 1
}
-// The launcher exports NODE_DISABLE_COMPILE_CACHE unconditionally, and then we re-enable
-// the cache here if necessary.
-if (process.env.NODE_COMPILE_CACHE) {
- delete process.env.NODE_DISABLE_COMPILE_CACHE
- require('node:module').enableCompileCache?.(process.env.NODE_COMPILE_CACHE)
+// Code coverage. We load this early on so that the coverage session sees as much of this
+// process compiled under it as possible. We require coverage.cjs conditionally to cut
+// down on code size for non-test targets.
+if (process.env.JS_BINARY__COVERAGE_REPORT || process.env.COVERAGE_DIR) {
+ require('./coverage.cjs')
}
const patchfs = require('./fs.cjs').patcher
diff --git a/js/private/test/image/checksum_test.expected b/js/private/test/image/checksum_test.expected
index 7f2d3e8..2948945 100644
--- a/js/private/test/image/checksum_test.expected
+++ b/js/private/test/image/checksum_test.expected
@@ -1,4 +1,4 @@
-0f7398d8d2fb575ee72775ddc412a8689f0335b76d4c2692b3fb0729e3376fb3 js/private/test/image/cksum_node.tar
+5bc8b423e2b42706a9a06b9188dd6c176ac00e63601bd9a6f71494285088dce9 js/private/test/image/cksum_node.tar
70b10220a2c05d87da4271c17c38ded8febc725e20e06f1c3809d2bb02ba4ae7 js/private/test/image/cksum_package_store_3p.tar
2cb6f678d6eb0b2e9d5e2637f41ae3f192233752f1ea2a55cede2531deec2a64 js/private/test/image/cksum_package_store_1p.tar
79afa99006aff19460354e72cf2634db693670d09ccc7531fbf27f1f20fe0a5f js/private/test/image/cksum_node_modules.tar
diff --git a/js/private/test/image/custom_layers_nomatch_test_node.listing b/js/private/test/image/custom_layers_nomatch_test_node.listing
index 3d00bf4..1774586 100644
--- a/js/private/test/image/custom_layers_nomatch_test_node.listing
+++ b/js/private/test/image/custom_layers_nomatch_test_node.listing
@@ -8,7 +8,7 @@
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/
--r-xr-xr-x 0 0 0 3356 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
+-r-xr-xr-x 0 0 0 3480 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
-r-xr-xr-x 0 0 0 37120 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/fs.cjs
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs++node+nodejs_linux_amd64/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs++node+nodejs_linux_amd64/bin/
diff --git a/js/private/test/image/custom_owner_test_node.listing b/js/private/test/image/custom_owner_test_node.listing
index d54cdfe..ca25d7b 100644
--- a/js/private/test/image/custom_owner_test_node.listing
+++ b/js/private/test/image/custom_owner_test_node.listing
@@ -7,7 +7,7 @@
drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/
drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/
drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/
--r-xr-xr-x 0 100 0 3356 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
+-r-xr-xr-x 0 100 0 3480 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
-r-xr-xr-x 0 100 0 37120 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/fs.cjs
drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs++node+nodejs_linux_amd64/
drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs++node+nodejs_linux_amd64/bin/
diff --git a/js/private/test/image/default_test_node.listing b/js/private/test/image/default_test_node.listing
index aca2d1f..8b6258b 100644
--- a/js/private/test/image/default_test_node.listing
+++ b/js/private/test/image/default_test_node.listing
@@ -7,7 +7,7 @@
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/
--r-xr-xr-x 0 0 0 3356 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
+-r-xr-xr-x 0 0 0 3480 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
-r-xr-xr-x 0 0 0 37120 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/fs.cjs
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs++node+nodejs_linux_amd64/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs++node+nodejs_linux_amd64/bin/
diff --git a/js/private/test/image/non_ascii/custom_layer_groups_test_node.listing b/js/private/test/image/non_ascii/custom_layer_groups_test_node.listing
index 97e64a5..2790778 100644
--- a/js/private/test/image/non_ascii/custom_layer_groups_test_node.listing
+++ b/js/private/test/image/non_ascii/custom_layer_groups_test_node.listing
@@ -9,7 +9,7 @@
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/node-bootstrap/
--r-xr-xr-x 0 0 0 3356 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
+-r-xr-xr-x 0 0 0 3480 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/rules_nodejs++node+nodejs_linux_amd64/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/rules_nodejs++node+nodejs_linux_amd64/bin/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/rules_nodejs++node+nodejs_linux_amd64/bin/nodejs/
diff --git a/js/private/test/image/platform_deps/rspack_linux_arm64_test_node.listing b/js/private/test/image/platform_deps/rspack_linux_arm64_test_node.listing
index 3dabb8f..096da4d 100644
--- a/js/private/test/image/platform_deps/rspack_linux_arm64_test_node.listing
+++ b/js/private/test/image/platform_deps/rspack_linux_arm64_test_node.listing
@@ -9,7 +9,7 @@
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/platform_deps/bin.runfiles/_main/js/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/platform_deps/bin.runfiles/_main/js/private/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/platform_deps/bin.runfiles/_main/js/private/node-bootstrap/
--r-xr-xr-x 0 0 0 3356 Jan 1 1970 ./app/js/private/test/image/platform_deps/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
+-r-xr-xr-x 0 0 0 3480 Jan 1 1970 ./app/js/private/test/image/platform_deps/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
-r-xr-xr-x 0 0 0 37120 Jan 1 1970 ./app/js/private/test/image/platform_deps/bin.runfiles/_main/js/private/node-bootstrap/fs.cjs
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/platform_deps/bin.runfiles/rules_nodejs++node+nodejs_linux_arm64/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/platform_deps/bin.runfiles/rules_nodejs++node+nodejs_linux_arm64/bin/
diff --git a/js/private/test/image/regex_edge_cases_test_node.listing b/js/private/test/image/regex_edge_cases_test_node.listing
index 3d00bf4..1774586 100644
--- a/js/private/test/image/regex_edge_cases_test_node.listing
+++ b/js/private/test/image/regex_edge_cases_test_node.listing
@@ -8,7 +8,7 @@
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/
--r-xr-xr-x 0 0 0 3356 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
+-r-xr-xr-x 0 0 0 3480 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/bootstrap.cjs
-r-xr-xr-x 0 0 0 37120 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-bootstrap/fs.cjs
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs++node+nodejs_linux_amd64/
drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs++node+nodejs_linux_amd64/bin/
diff --git a/js/private/test/js_binary_sh/BUILD.bazel b/js/private/test/js_binary_sh/BUILD.bazel
index 3efd3aa..ca31ee4 100644
--- a/js/private/test/js_binary_sh/BUILD.bazel
+++ b/js/private/test/js_binary_sh/BUILD.bazel
@@ -238,21 +238,22 @@
expected = "export JSON_ENCODE=\"[\\\"twx\\\"]\"",
)
-####################################################################################################
-# Node module compile cache: off by default, re-enabled by node-bootstrap/bootstrap.cjs when
-# NODE_COMPILE_CACHE is set.
+##############################################################################################
+# Node module compile cache: off by default, but can be enabled by setting NODE_COMPILE_CACHE.
# https://github.com/aspect-build/rules_js/issues/2937
write_file(
name = "write_compile_cache",
out = "compile_cache.js",
# Ask Node to enable the cache (into a sandbox-relative dir so nothing leaks out) and
- # report the resulting status. It comes back DISABLED unless NODE_COMPILE_CACHE was set.
+ # report the exact status constant it returns.
content = ["""
const { enableCompileCache, constants } = require("node:module");
const { status } = enableCompileCache("node-compile-cache");
- const disabled = status === constants.compileCacheStatus.DISABLED;
- console.log("COMPILE_CACHE_DISABLED=" + (disabled ? "yes" : "no"));
+ const name = Object.keys(constants.compileCacheStatus).find(
+ (key) => constants.compileCacheStatus[key] === status
+ );
+ console.log("COMPILE_CACHE_STATUS=" + name);
"""],
)
@@ -273,11 +274,12 @@
assert_contains(
name = "compile_cache_disabled_by_default_test",
actual = ":compile-cache-default-stdout",
- expected = "COMPILE_CACHE_DISABLED=yes",
+ expected = "COMPILE_CACHE_STATUS=DISABLED",
)
-# Opt-in: an explicit NODE_COMPILE_CACHE (relative, so it stays inside the sandbox)
-# means the cache should be left enabled. Prepares for #2938.
+# Opt-in: an explicit NODE_COMPILE_CACHE (relative, so it stays inside the sandbox) means
+# the cache should be enabled. Prepares for #2938. This variable will cause node to enable
+# the cache at startup, so we will get a status of ALREADY_ENABLED.
js_binary(
name = "compile_cache_optin",
entry_point = "compile_cache.js",
@@ -294,7 +296,7 @@
assert_contains(
name = "compile_cache_optin_test",
actual = ":compile-cache-optin-stdout",
- expected = "COMPILE_CACHE_DISABLED=no",
+ expected = "COMPILE_CACHE_STATUS=ALREADY_ENABLED",
)
# bazel run: the cache is disabled here too for now (simulated via the env attribute);
@@ -315,13 +317,13 @@
assert_contains(
name = "compile_cache_bazel_run_test",
actual = ":compile-cache-bazel-run-stdout",
- expected = "COMPILE_CACHE_DISABLED=yes",
+ expected = "COMPILE_CACHE_STATUS=DISABLED",
)
-# Node gives NODE_DISABLE_COMPILE_CACHE precedence over NODE_COMPILE_CACHE, but we do the
-# opposite.
+# If both variables are set, then NODE_DISABLE_COMPILE_CACHE wins, following node's
+# behavior.
js_binary(
- name = "compile_cache_dir_wins_over_disable",
+ name = "compile_cache_disable_wins_over_dir",
entry_point = "compile_cache.js",
env = {
"NODE_COMPILE_CACHE": "node-compile-cache",
@@ -330,14 +332,14 @@
)
js_run_binary(
- name = "_compile_cache_dir_wins_over_disable",
+ name = "_compile_cache_disable_wins_over_dir",
silent_on_success = False,
- stdout = "compile-cache-dir-wins-over-disable-stdout",
- tool = ":compile_cache_dir_wins_over_disable",
+ stdout = "compile-cache-disable-wins-over-dir-stdout",
+ tool = ":compile_cache_disable_wins_over_dir",
)
assert_contains(
- name = "compile_cache_dir_wins_over_disable_test",
- actual = ":compile-cache-dir-wins-over-disable-stdout",
- expected = "COMPILE_CACHE_DISABLED=no",
+ name = "compile_cache_disable_wins_over_dir_test",
+ actual = ":compile-cache-disable-wins-over-dir-stdout",
+ expected = "COMPILE_CACHE_STATUS=DISABLED",
)
diff --git a/js/private/test/snapshots/launcher.sh b/js/private/test/snapshots/launcher.sh
index 504b857..d006907 100644
--- a/js/private/test/snapshots/launcher.sh
+++ b/js/private/test/snapshots/launcher.sh
@@ -506,10 +506,6 @@
fi
export JS_BINARY__FS_PATCH_ROOTS
-# Disable Node's module compile cache by default (aspect-build/rules_js#2937).
-# We will re-enable it at runtime if NODE_COMPILE_CACHE is set.
-export NODE_DISABLE_COMPILE_CACHE=1
-
# Put the node wrapper directory and optionally the npm wrapper directory on the path so that
# child processes can find them.
if [ "${npm_bin_dir:-}" ]; then