Rules for running JavaScript programs under Bazel, as tools or with bazel run
or bazel test
.
For example, this binary references the acorn
npm package which was already linked
using an API like npm_link_all_packages
.
load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_test")
js_binary(
name = "bin",
# Reference the location where the acorn npm module was linked in the root Bazel package
data = ["//:node_modules/acorn"],
entry_point = "require_acorn.js",
)
Rules
js_binary
Execute a program in the node.js runtime.
The version of node is determined by Bazel's toolchain selection. In the WORKSPACE you used
nodejs_register_toolchains
to provide options to Bazel. Then Bazel selects from these options
based on the requested target platform. Use the
--toolchain_resolution_debug
Bazel option to see more detail about the selection.
This rules requires that Bazel was run with
--enable_runfiles
.
Example usage (generated)
load("@aspect_rules_js//js:defs.bzl", "js_binary")
js_binary(
# A unique name for this target.
name = "",
# Whether runfiles are enabled in the current build configuration
enable_runfiles = false,
# The main script which is evaluated by node.js
entry_point = "",
)
name
A unique name for this target.
chdir
Working directory to run the binary or test in, relative to the workspace.
By default, js_binary
runs in the root of the output tree.
To run in the directory containing the js_binary
use
chdir = package_name()
(or if you're in a macro, use native.package_name()
)
WARNING: this will affect other paths passed to the program, either as arguments or in configuration files, which are workspace-relative.
You may need ../../
segments to re-relativize such paths to the new working directory.
In a BUILD
file you could do something like this to point to the output path:
js_binary(
...
chdir = package_name(),
# ../.. segments to re-relative paths from the chdir back to workspace;
# add an additional 3 segments to account for running js_binary running
# in the root of the output tree
args = ["/".join([".."] * len(package_name().split("/")) + "$(rootpath //path/to/some:file)"],
)
copy_data_to_bin
When True, data
files and the entry_point
file are copied to the Bazel output tree before being passed
as inputs to runfiles.
Defaults to True so that a js_binary
with the default value is compatible with js_run_binary
with
use_execroot_entry_point
set to True, the default there.
Setting this to False is more optimal in terms of inputs, but there is a yet unresolved issue of ESM imports
skirting the node fs patches and escaping the sandbox: https://github.com/aspect-build/rules_js/issues/362.
This is hit in some popular test runners such as mocha, which use native import()
statements
(https://github.com/aspect-build/rules_js/pull/353). When set to False, a program such as mocha that uses ESM
imports may escape the execroot by following symlinks into the source tree. When set to True, such a program
would escape the sandbox but will end up in the output tree where node_modules
and other inputs required
will be available.
data
Runtime dependencies of the program.
The transitive closure of the data
dependencies will be available in
the .runfiles folder for this binary/test.
You can use the @bazel/runfiles
npm library to access these files
at runtime.
npm packages are also linked into the .runfiles/node_modules
folder
so they may be resolved directly from runfiles.
enable_runfiles
Whether runfiles are enabled in the current build configuration.
Typical usage of this rule is via a macro which automatically sets this
attribute based on a config_setting
rule.
entry_point
The main script which is evaluated by node.js.
This is the module referenced by the require.main
property in the runtime.
This must be a target that provides a single file or a DirectoryPathInfo
from @aspect_bazel_lib//lib::directory_path.bzl
.
See https://github.com/aspect-build/bazel-lib/blob/main/docs/directory_path.md
for more info on creating a target that provides a DirectoryPathInfo
.
env
Environment variables of the action.
Subject to $(location)
and make variable expansion.
expected_exit_code
The expected exit code.
Can be used to write tests that are expected to fail.
include_declarations
When True, declarations
and transitive_declarations
from JsInfo
providers in data targets are included in the runfiles of the target.
Defaults to false since declarations are generally not needed at runtime and introducing them could slow down developer round trip time due to having to generate typings on source file changes.
include_npm
When True, npm is included in the runfiles of the target.
An npm binary is also added on the PATH so tools can spawn npm processes. This is a bash script on Linux and MacOS and a batch script on Windows.
A minimum of rules_nodejs version 5.7.0 is required which contains the Node.js toolchain changes to use npm.
include_npm_linked_packages
When True, files in npm_linked_packages
and transitive_npm_linked_packages
from JsInfo
providers in data targets are included in the runfiles of the target.
transitive_files
from NpmPackageStoreInfo
providers in data targets are also included in the runfiles of the target.
include_transitive_sources
When True, transitive_sources
from JsInfo
providers in data targets are included in the runfiles of the target.
log_level
Set the logging level.
Log from are written to stderr. They will be supressed on success when running as the tool of a js_run_binary when silent_on_success is True. In that case, they will be shown only on a build failure along with the stdout & stderr of the node tool being run.
node_options
Options to pass to the node invocation on the command line.
https://nodejs.org/api/cli.html
These options are passed directly to the node invocation on the command line. Options passed here will take precendence over options passed via the NODE_OPTIONS environment variable. Options passed here are not added to the NODE_OPTIONS environment variable so will not be automatically picked up by child processes that inherit that enviroment variable.
patch_node_fs
Patch the to Node.js fs
API (https://nodejs.org/api/fs.html) for this node program
to prevent the program from following symlinks out of the execroot, runfiles and the sandbox.
When enabled, js_binary
patches the Node.js sync and async fs
API functions lstat
,
readlink
, realpath
, readdir
and opendir
so that the node program being
run cannot resolve symlinks out of the execroot and the runfiles tree. When in the sandbox,
these patches prevent the program being run from resolving symlinks out of the sandbox.
When disabled, node programs can leave the execroot, runfiles and sandbox by following symlinks which can lead to non-hermetic behavior.
preserve_symlinks_main
When True, the --preserve-symlinks-main flag is passed to node.
This prevents node from following an ESM entry script out of runfiles and the sandbox. This can happen for .mjs
ESM entry points where the fs node patches, which guard the runfiles and sandbox, are not applied.
See https://github.com/aspect-build/rules_js/issues/362 for more information. Once #362 is resolved,
the default for this attribute can be set to False.
This flag was added in Node.js v10.2.0 (released 2018-05-23). If your node toolchain is configured to use a Node.js version older than this you'll need to set this attribute to False.
See https://nodejs.org/api/cli.html#--preserve-symlinks-main for more information.
js_test
Identical to js_binary, but usable under bazel test
.
Bazel will set environment variables when a test target is run under bazel test
and bazel run
that a test runner can use.
A runner can write arbitrary outputs files it wants Bazel to pickup and save with the test logs to
TEST_UNDECLARED_OUTPUTS_DIR
. These get zipped up and saved along with the test logs.
JUnit XML reports can be written to XML_OUTPUT_FILE
for Bazel to consume.
TEST_TMPDIR
is an absolute path to a private writeable directory that the test runner can use for
creating temporary files.
LCOV coverage reports can be written to COVERAGE_OUTPUT_FILE
when running under bazel coverage
or if the --coverage
flag is set.
See the Bazel Test encyclopedia for details on the contract between Bazel and a test runner.
Example usage (generated)
load("@aspect_rules_js//js:defs.bzl", "js_test")
js_test(
# A unique name for this target.
name = "",
# Whether runfiles are enabled in the current build configuration
enable_runfiles = false,
# The main script which is evaluated by node.js
entry_point = "",
)
name
A unique name for this target.
chdir
Working directory to run the binary or test in, relative to the workspace.
By default, js_binary
runs in the root of the output tree.
To run in the directory containing the js_binary
use
chdir = package_name()
(or if you're in a macro, use native.package_name()
)
WARNING: this will affect other paths passed to the program, either as arguments or in configuration files, which are workspace-relative.
You may need ../../
segments to re-relativize such paths to the new working directory.
In a BUILD
file you could do something like this to point to the output path:
js_binary(
...
chdir = package_name(),
# ../.. segments to re-relative paths from the chdir back to workspace;
# add an additional 3 segments to account for running js_binary running
# in the root of the output tree
args = ["/".join([".."] * len(package_name().split("/")) + "$(rootpath //path/to/some:file)"],
)
copy_data_to_bin
When True, data
files and the entry_point
file are copied to the Bazel output tree before being passed
as inputs to runfiles.
Defaults to True so that a js_binary
with the default value is compatible with js_run_binary
with
use_execroot_entry_point
set to True, the default there.
Setting this to False is more optimal in terms of inputs, but there is a yet unresolved issue of ESM imports
skirting the node fs patches and escaping the sandbox: https://github.com/aspect-build/rules_js/issues/362.
This is hit in some popular test runners such as mocha, which use native import()
statements
(https://github.com/aspect-build/rules_js/pull/353). When set to False, a program such as mocha that uses ESM
imports may escape the execroot by following symlinks into the source tree. When set to True, such a program
would escape the sandbox but will end up in the output tree where node_modules
and other inputs required
will be available.
data
Runtime dependencies of the program.
The transitive closure of the data
dependencies will be available in
the .runfiles folder for this binary/test.
You can use the @bazel/runfiles
npm library to access these files
at runtime.
npm packages are also linked into the .runfiles/node_modules
folder
so they may be resolved directly from runfiles.
enable_runfiles
Whether runfiles are enabled in the current build configuration.
Typical usage of this rule is via a macro which automatically sets this
attribute based on a config_setting
rule.
entry_point
The main script which is evaluated by node.js.
This is the module referenced by the require.main
property in the runtime.
This must be a target that provides a single file or a DirectoryPathInfo
from @aspect_bazel_lib//lib::directory_path.bzl
.
See https://github.com/aspect-build/bazel-lib/blob/main/docs/directory_path.md
for more info on creating a target that provides a DirectoryPathInfo
.
env
Environment variables of the action.
Subject to $(location)
and make variable expansion.
expected_exit_code
The expected exit code.
Can be used to write tests that are expected to fail.
include_declarations
When True, declarations
and transitive_declarations
from JsInfo
providers in data targets are included in the runfiles of the target.
Defaults to false since declarations are generally not needed at runtime and introducing them could slow down developer round trip time due to having to generate typings on source file changes.
include_npm
When True, npm is included in the runfiles of the target.
An npm binary is also added on the PATH so tools can spawn npm processes. This is a bash script on Linux and MacOS and a batch script on Windows.
A minimum of rules_nodejs version 5.7.0 is required which contains the Node.js toolchain changes to use npm.
include_npm_linked_packages
When True, files in npm_linked_packages
and transitive_npm_linked_packages
from JsInfo
providers in data targets are included in the runfiles of the target.
transitive_files
from NpmPackageStoreInfo
providers in data targets are also included in the runfiles of the target.
include_transitive_sources
When True, transitive_sources
from JsInfo
providers in data targets are included in the runfiles of the target.
log_level
Set the logging level.
Log from are written to stderr. They will be supressed on success when running as the tool of a js_run_binary when silent_on_success is True. In that case, they will be shown only on a build failure along with the stdout & stderr of the node tool being run.
node_options
Options to pass to the node invocation on the command line.
https://nodejs.org/api/cli.html
These options are passed directly to the node invocation on the command line. Options passed here will take precendence over options passed via the NODE_OPTIONS environment variable. Options passed here are not added to the NODE_OPTIONS environment variable so will not be automatically picked up by child processes that inherit that enviroment variable.
patch_node_fs
Patch the to Node.js fs
API (https://nodejs.org/api/fs.html) for this node program
to prevent the program from following symlinks out of the execroot, runfiles and the sandbox.
When enabled, js_binary
patches the Node.js sync and async fs
API functions lstat
,
readlink
, realpath
, readdir
and opendir
so that the node program being
run cannot resolve symlinks out of the execroot and the runfiles tree. When in the sandbox,
these patches prevent the program being run from resolving symlinks out of the sandbox.
When disabled, node programs can leave the execroot, runfiles and sandbox by following symlinks which can lead to non-hermetic behavior.
preserve_symlinks_main
When True, the --preserve-symlinks-main flag is passed to node.
This prevents node from following an ESM entry script out of runfiles and the sandbox. This can happen for .mjs
ESM entry points where the fs node patches, which guard the runfiles and sandbox, are not applied.
See https://github.com/aspect-build/rules_js/issues/362 for more information. Once #362 is resolved,
the default for this attribute can be set to False.
This flag was added in Node.js v10.2.0 (released 2018-05-23). If your node toolchain is configured to use a Node.js version older than this you'll need to set this attribute to False.
See https://nodejs.org/api/cli.html#--preserve-symlinks-main for more information.
Macros and Functions
js_binary_lib.create_launcher
Example usage (generated)
load("@aspect_rules_js//js:defs.bzl", "js_binary_lib")
js_binary_lib.create_launcher(
ctx = None,
log_prefix_rule_set = None,
log_prefix_rule = None,
)
ctx
log_prefix_rule_set
log_prefix_rule
fixed_args
fixed_env
js_binary_lib.implementation
Example usage (generated)
load("@aspect_rules_js//js:defs.bzl", "js_binary_lib")
js_binary_lib.implementation(
ctx = None,
)