Skip to main content
Documentation for @aspect_rules_js@v3.0.0 View source
Rules for running JavaScript programs

Rule: js_library

A library of JavaScript sources. Provides JsInfo, the primary provider used in rules_js and derivative rule sets. Declaration files are handled separately from sources since they are generally not needed at runtime and build rules, such as ts_project, are optimal in their build graph if they only depend on types from deps since these they don’t need the JavaScript source files from deps to typecheck. Linked npm dependences are also handled separately from sources since not all rules require them and it is optimal for these rules to not depend on them in the build graph. NB: js_library copies all source files to the output tree before providing them in JsInfo. See https://github.com/aspect-build/rules_js/tree/dbb5af0d2a9a2bb50e4cf4a96dbc582b27567155/docs#javascript for more context on why we do this.

Attributes

name
name
required
A unique name for this target.
srcs
list of labels
default:"[]"
Source files that are included in this library.This includes all your checked-in code and any generated source files.The transitive npm dependencies, transitive sources & runfiles of targets in the srcs attribute are added to the runfiles of this target. They should appear in the ‘*.runfiles’ area of any executable which is output by or has a runtime dependency on this target.Source files that are JSON files, declaration files or directory artifacts will be automatically provided as “types” available to downstream rules for type checking. To explicitly provide source files as “types” available to downstream rules for type checking that do not match these criteria, move those files to the types attribute instead.
types
list of labels
default:"[]"
Same as srcs except all files are also provided as “types” available to downstream rules for type checking.For example, a js_library with only .js files that are intended to be imported as .js files by downstream type checking rules such as ts_project would list those files in types:
js_library(
    name = "js_lib",
    types = ["index.js"],
)
deps
list of labels
default:"[]"
Dependencies of this target.This may include other js_library targets or other targets that provide JsInfoThe transitive npm dependencies, transitive sources & runfiles of targets in the deps attribute are added to the runfiles of this target. They should appear in the ‘*.runfiles’ area of any executable which is output by or has a runtime dependency on this target.If this list contains linked npm packages, npm package store targets or other targets that provide JsInfo, NpmPackageStoreInfo providers are gathered from JsInfo. This is done directly from the npm_package_store_infos field of these. For linked npm package targets, the underlying npm_package_store target(s) that back the links are used. Gathered NpmPackageStoreInfo providers are propagated to the direct dependencies of downstream linked targets.NB: Linked npm package targets that are “dev” dependencies do not forward their underlying npm_package_store target(s) through npm_package_store_infos and will therefore not be propagated to the direct dependencies of downstream linked targets. npm packages that come in from npm_translate_lock are considered “dev” dependencies if they are have dev: true set in the pnpm lock file. This should be all packages that are only listed as “devDependencies” in all package.json files within the pnpm workspace. This behavior is intentional to mimic how devDependencies work in published npm packages.
data
list of labels
default:"[]"
Runtime dependencies to include in binaries/tests that depend on this target.The transitive npm dependencies, transitive sources, default outputs and runfiles of targets in the data attribute are added to the runfiles of this target. They should appear in the ‘*.runfiles’ area of any executable which has a runtime dependency on this target.If this list contains linked npm packages, npm package store targets or other targets that provide JsInfo, NpmPackageStoreInfo providers are gathered from JsInfo. This is done directly from the npm_package_store_infos field of these. For linked npm package targets, the underlying npm_package_store target(s) that back the links are used. Gathered NpmPackageStoreInfo providers are propagated to the direct dependencies of downstream linked targets.NB: Linked npm package targets that are “dev” dependencies do not forward their underlying npm_package_store target(s) through npm_package_store_infos and will therefore not be propagated to the direct dependencies of downstream linked targets. npm packages that come in from npm_translate_lock are considered “dev” dependencies if they are have dev: true set in the pnpm lock file. This should be all packages that are only listed as “devDependencies” in all package.json files within the pnpm workspace. This behavior is intentional to mimic how devDependencies work in published npm packages.
no_copy_to_bin
list of labels
default:"[]"
List of files to not copy to the Bazel output tree when copy_data_to_bin is True.This is useful for exceptional cases where a copy_to_bin is not possible or not suitable for an input file such as a file in an external repository. In most cases, this option is not needed. See copy_data_to_bin docstring for more info.
copy_data_to_bin
boolean
default:"True"
When True, data files are copied to the Bazel output tree before being passed as inputs to runfiles.

Rule: js_info_files

Gathers files from the JsInfo providers from targets in srcs and provides them as default outputs. This helper rule is used by the js_run_binary macro.

Attributes

name
name
required
A unique name for this target.
srcs
list of labels
default:"[]"
List of targets to gather files from.
include_sources
boolean
default:"True"
When True, sources from JsInfo providers in srcs targets are included in the default outputs of the target.
include_transitive_sources
boolean
default:"True"
When True, transitive_sources from JsInfo providers in srcs targets are included in the default outputs of the target.
include_types
boolean
default:"False"
When True, types from JsInfo providers in srcs targets are included in the default outputs of the target.Defaults to False since types 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.NB: These are types from direct srcs dependencies only. You may also need to set include_transitive_types to True.
include_transitive_types
boolean
default:"False"
When True, transitive_types from JsInfo providers in srcs targets are included in the default outputs of the target.Defaults to False since types 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_sources
boolean
default:"True"
When True, files in npm_sources from JsInfo providers in srcs targets are included in the default outputs of the target.transitive_files from NpmPackageStoreInfo providers in srcs targets are also included in the default outputs of the target.

Rule: js_image_layer

Create container image layers from js_binary targets. By design, js_image_layer doesn’t have any preference over which rule assembles the container image. This means the downstream rule (oci_image from rules_oci or container_image from rules_docker) must set a proper workdir and cmd to for the container work. A proper cmd usually looks like /[ js_image_layer 'root' ]/[ package name of js_image_layer 'binary' target ]/[ name of js_image_layer 'binary' target ], unless you have a custom launcher script that invokes the entry_point of the js_binary in a different path. On the other hand, workdir has to be set to the “runfiles tree root” which would be exactly cmd but with .runfiles/[ name of the workspace ] suffix. When using bzlmod then name of the local workspace is always _main. If workdir is not set correctly, some attributes such as chdir might not work properly. js_image_layer creates up to 5 layers depending on what files are included in the runfiles of the provided binary target.
  1. node layer contains the Node.js toolchain
  2. package_store_3p layer contains all 3p npm deps in the node_modules/.aspect_rules_js package store
  3. package_store_1p layer contains all 1p npm deps in the node_modules/.aspect_rules_js package store
  4. node_modules layer contains all node_modules/* symlinks which point into the package store
  5. app layer contains all files that don’t fall into any of the above layers
If no files are found in the runfiles of the binary target for one of the layers above, that layer is not generated. All generated layer tarballs are provided as DefaultInfo files.
The rules_js node_modules/.aspect_rules_js package store follows the same pattern as the pnpm node_modules/.pnpm virtual store. For more information see https://pnpm.io/symlinked-node-modules-structure.
js_image_layer also provides an OutputGroupInfo with outputs for each of the layers above which can be used to reference an individual layer with using filegroup with output_group. For example,
js_image_layer(
    name = "layers",
    binary = ":bin",
    root = "/app",
)

filegroup(
    name = "app_tar",
    srcs = [":layers"],
    output_group = "app",
)
WARNING: The structure of the generated layers are not subject to semver guarantees and may change without a notice. However, it is guaranteed to work when all generated layers are provided together in the order specified above.
js_image_layer supports transitioning to specific platform to allow building multi-platform container images. A partial example using rules_oci with transition to linux/amd64 platform.
load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_image_layer")
load("@rules_oci//oci:defs.bzl", "oci_image")

js_binary(
    name = "bin",
    entry_point = "main.js",
)

platform(
    name = "amd64_linux",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
    ],
)

js_image_layer(
    name = "layers",
    binary = ":bin",
    platform = ":amd64_linux",
    root = "/app",
)

oci_image(
    name = "image",
    cmd = ["/app/bin"],
    entrypoint = ["bash"],
    tars = [
        ":layers"
    ],
    workdir = "/app/bin.runfiles/_main",
)
A partial example using rules_oci to create multi-platform images.
load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_image_layer")
load("@rules_oci//oci:defs.bzl", "oci_image", "oci_image_index")

js_binary(
    name = "bin",
    entry_point = "main.js",
)

[
    platform(
        name = "linux_{}".format(arch),
        constraint_values = [
            "@platforms//os:linux",
            "@platforms//cpu:{}".format(arch if arch != "amd64" else "x86_64"),
        ],
    )

    js_image_layer(
        name = "{}_layers".format(arch),
        binary = ":bin",
        platform = ":linux_{arch}",
        root = "/app",
    )

    oci_image(
        name = "{}_image".format(arch),
        cmd = ["/app/bin"],
        entrypoint = ["bash"],
        tars = [
            ":{}_layers".format(arch)
        ],
        workdir = "/app/bin.runfiles/_main",
    )

    for arch in ["amd64", "arm64"]
]

oci_image_index(
    name = "image",
    images = [
        ":arm64_image",
        ":amd64_image"
    ]
)
For better performance, it is recommended to split the large parts of a js_binary to have a separate layer. The matching order for layer groups is as follows:
  1. layer_groups are checked in order first
  2. If no match is found for layer_groups, the default layer groups are checked.
  3. Any remaining files are placed into the app layer.
The default layer groups are as follows and always created.
{
    "node": "/js/private/node-patches/|/bin/nodejs/",
    "package_store_1p": "\.aspect_rules_js/.*@0\.0\.0/node_modules",
    "package_store_3p": "\.aspect_rules_js/.*/node_modules",
    "node_modules": "/node_modules/",
    "app": "", # empty means just match anything.
}

Attributes

name
name
required
A unique name for this target.
binary
label
required
Label to an js_binary target
root
string
default:"\"\""
Path where the files from js_binary will reside in. eg: /apps/app1 or /app
owner
string
default:"0:0"
Owner of the entries, in GID:UID format. By default 0:0 (root, root) is used.
directory_mode
string
default:"0755"
Mode of the directories, in octal format. By default 0755 is used.
file_mode
string
default:"0555"
Mode of the files, in octal format. By default 0555 is used.
platform
label
default:"None"
Platform to transition.
Preserve symlinks for entries matching the pattern. By default symlinks within the node_modules is preserved.
layer_groups
dictionary: String → String
default:"{}"
Layer groups to create. These are utilized to categorize files into distinct layers, determined by their respective paths. The expected format for each entry is "<key>": "<value>", where <key> MUST be a valid Bazel and JavaScript identifier (alphanumeric characters), and <value> MAY be either an empty string (signifying a universal match) or a valid regular expression.

Function: js_binary

Parameters

kwargs
unknown

Function: js_test

Parameters

kwargs
unknown

Function: js_run_devserver

Runs a devserver via binary target or command. A simple http-server, for example, can be setup as follows,
load("@aspect_rules_js//js:defs.bzl", "js_run_devserver")
load("@npm//:http-server/package_json.bzl", http_server_bin = "bin")

http_server_bin.http_server_binary(
    name = "http_server",
)

js_run_devserver(
    name = "serve",
    args = ["."],
    data = ["index.html"],
    tool = ":http_server",
)
A Next.js devserver can be setup as follows,
js_run_devserver(
    name = "dev",
    args = ["dev"],
    command = "./node_modules/.bin/next",
    data = [
        "next.config.js",
        "package.json",
        ":node_modules/next",
        ":node_modules/react",
        ":node_modules/react-dom",
        ":node_modules/typescript",
        "//pages",
        "//public",
        "//styles",
    ],
)
where the ./node_modules/.bin/next bin entry of Next.js is configured in npm_translate_lock as such,
npm_translate_lock(
    name = "npm",
    bins = {
        # derived from "bin" attribute in node_modules/next/package.json
        "next": {
            "next": "./dist/bin/next",
        },
    },
    pnpm_lock = "//:pnpm-lock.yaml",
)
and run in watch mode using ibazel with ibazel run //:dev. The devserver specified by either tool or command is run in a custom sandbox that is more compatible with devserver watch modes in Node.js tools such as Webpack and Next.js. The custom sandbox is populated with the default outputs of all targets in data as well as transitive sources & npm links. As an optimization, package store files are explicitly excluded from the sandbox since the npm links will point to the package store in the execroot and Node.js will follow those links as it does within the execroot. As a result, rules_js npm package link targets such as //:node_modules/next are handled efficiently. Since these targets are symlinks in the output tree, they are recreated as symlinks in the custom sandbox and do not incur a full copy of the underlying npm packages. Supports running with ibazel. Only data files that change on incremental builds are synchronized when running with ibazel. Note that the use of alias targets is not supported by ibazel: https://github.com/bazelbuild/bazel-watcher/issues/100

Parameters

name
unknown
required
A unique name for this target.
tool
unknown
default:"None"
The devserver binary target to run.Only one of command or tool may be specified.
command
unknown
default:"None"
The devserver command to run.For example, this could be the bin entry of an npm package that is included in data such as ./node_modules/.bin/next.Using the bin entry of next, for example, resolves issues with Next.js and React being found in multiple node_modules trees when next is run as an encapsulated js_binary tool.Only one of command or tool may be specified.
grant_sandbox_write_permissions
unknown
default:"False"
If set, write permissions is set on all files copied to the custom sandbox.This can be useful to support some devservers such as Next.js which may, under some circumstances, try to modify files when running.See https://github.com/aspect-build/rules_js/issues/935 for more context.
use_execroot_entry_point
unknown
default:"True"
Use the entry_point script of the js_binary tool that is in the execroot output tree instead of the copy that is in runfiles.Using the entry point script that is in the execroot output tree means that there will be no conflicting runfiles node_modules in the node_modules resolution path which can confuse npm packages such as next and react that don’t like being resolved in multiple node_modules trees. This more closely emulates the environment that tools such as Next.js see when they are run outside of Bazel.When True, the js_binary tool must have copy_data_to_bin set to True (the default) so that all data files needed by the binary are available in the execroot output tree. This requirement can be turned off with by setting allow_execroot_entry_point_with_no_copy_data_to_bin to True.
allow_execroot_entry_point_with_no_copy_data_to_bin
unknown
default:"False"
Turn off validation that the js_binary tool has copy_data_to_bin set to True when use_execroot_entry_point is set to True.See use_execroot_entry_point doc for more info.
kwargs
unknown
All other args from js_binary except for entry_point which is set implicitly.entry_point is set implicitly by js_run_devserver and cannot be overridden.See https://docs.aspect.build/rules/aspect_rules_js/docs/js_binary

Function: js_run_binary

Wrapper around @bazel_lib run_binary that adds convenience attributes for using a js_binary tool. This rule does not require Bash native.genrule. The following environment variables are made available to the Node.js runtime based on available Bazel Make variables:
  • BAZEL_BINDIR: the bazel bin directory; equivalent to the $(BINDIR) Make variable of the js_run_binary target
  • BAZEL_COMPILATION_MODE: One of fastbuild, dbg, or opt as set by --compilation_mode; equivalent to $(COMPILATION_MODE) Make variable of the js_run_binary target
  • BAZEL_TARGET_CPU: the target cpu architecture; equivalent to $(TARGET_CPU) Make variable of the js_run_binary target
The following environment variables are made available to the Node.js runtime based on the rule context:
  • BAZEL_BUILD_FILE_PATH: the path to the BUILD file of the bazel target being run; equivalent to ctx.build_file_path of the js_run_binary target’s rule context
  • BAZEL_PACKAGE: the package of the bazel target being run; equivalent to ctx.label.package of the js_run_binary target’s rule context
  • BAZEL_TARGET_NAME: the full label of the bazel target being run; a stringified version of ctx.label of the js_run_binary target’s rule context
  • BAZEL_TARGET: the name of the bazel target being run; equivalent to ctx.label.name of the js_run_binary target’s rule context
  • BAZEL_WORKSPACE: the bazel repository name; equivalent to ctx.workspace_name of the js_run_binary target’s rule context

Parameters

name
unknown
required
Target name
tool
unknown
required
The tool to run in the action.Should be a js_binary rule. Use Aspect bazel-lib’s run_binary (https://github.com/bazel-contrib/bazel-lib/blob/main/lib/run_binary.bzl) for other *_binary rule types.
env
unknown
default:"{}"
Environment variables of the action.Subject to $(location) and make variable expansion.
srcs
unknown
default:"[]"
Additional inputs of the action.These labels are available for $(location) expansion in args and env.
outs
unknown
default:"[]"
Output files generated by the action.These labels are available for $(location) expansion in args and env.
out_dirs
unknown
default:"[]"
Output directories generated by the action.These labels are not available for $(location) expansion in args and env since they are not pre-declared labels created via attr.output_list(). Output directories are declared instead by ctx.actions.declare_directory.
args
unknown
default:"[]"
Command line arguments of the binary.Subject to $(location) and make variable expansion.
chdir
unknown
default:"None"
Working directory to run the build action in.This overrides the chdir value if set on the js_binary tool target.By default, js_binary tools run in the root of the output tree. For more context on why, please read the aspect_rules_js README https://github.com/aspect-build/rules_js/tree/dbb5af0d2a9a2bb50e4cf4a96dbc582b27567155#running-nodejs-programs.To run in the directory containing the js_run_binary in the output tree, 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.
stdout
unknown
default:"None"
Output file to capture the stdout of the binary.This can later be used as an input to another target subject to the same semantics as outs.If the binary creates outputs and these are declared, they must still be created.
stderr
unknown
default:"None"
Output file to capture the stderr of the binary to.This can later be used as an input to another target subject to the same semantics as outs.If the binary creates outputs and these are declared, they must still be created.
exit_code_out
unknown
default:"None"
Output file to capture the exit code of the binary to.This can later be used as an input to another target subject to the same semantics as outs. Note that setting this will force the binary to exit 0.If the binary creates outputs and these are declared, they must still be created.
silent_on_success
unknown
default:"True"
produce no output on stdout nor stderr when program exits with status code 0.This makes node binaries match the expected bazel paradigm.
use_execroot_entry_point
unknown
default:"True"
Use the entry_point script of the js_binary tool that is in the execroot output tree instead of the copy that is in runfiles.Runfiles of tool are all hoisted to srcs of the underlying run_binary so they are included as execroot inputs to the action.Using the entry point script that is in the execroot output tree means that there will be no conflicting runfiles node_modules in the node_modules resolution path which can confuse npm packages such as next and react that don’t like being resolved in multiple node_modules trees. This more closely emulates the environment that tools such as Next.js see when they are run outside of Bazel.When True, the js_binary tool must have copy_data_to_bin set to True (the default) so that all data files needed by the binary are available in the execroot output tree. This requirement can be turned off with by setting allow_execroot_entry_point_with_no_copy_data_to_bin to True.
copy_srcs_to_bin
unknown
default:"True"
When True, all srcs files are copied to the output tree that are not already there.
include_sources
unknown
default:"True"
see js_info_files documentation
include_types
unknown
default:"False"
see js_info_files documentation
include_transitive_sources
unknown
default:"True"
see js_info_files documentation
include_transitive_types
unknown
default:"False"
see js_info_files documentation
include_npm_sources
unknown
default:"True"
see js_info_files documentation
log_level
unknown
default:"None"
Set the logging level of the js_binary tool.This overrides the log level set on the js_binary tool target.
mnemonic
unknown
default:"JsRunBinary"
A one-word description of the action, for example, CppCompile or GoLink.
progress_message
unknown
default:"None"
Progress message to show to the user during the build, for example, “Compiling foo.cc to create foo.o”. The message may contain %{label}, %{input}, or %{output} patterns, which are substituted with label string, first input, or output’s path, respectively. Prefer to use patterns instead of static strings, because the former are more efficient.
execution_requirements
unknown
default:"None"
Information for scheduling the action.For example,
execution_requirements = {
    "no-cache": "1",
},
See https://docs.bazel.build/versions/main/be/common-definitions.html#common.tags for useful keys.
stamp
unknown
default:"0"
Whether to include build status files as inputs to the tool. Possible values:
  • stamp = 0 (default): Never include build status files as inputs to the tool. This gives good build result caching. Most tools don’t use the status files, so including them in --stamp builds makes those builds have many needless cache misses. (Note: this default is different from most rules with an integer-typed stamp attribute.)
  • stamp = 1: Always include build status files as inputs to the tool, even in —nostamp builds. This setting should be avoided, since it is non-deterministic. It potentially causes remote cache misses for the target and any downstream actions that depend on the result.
  • stamp = -1: Inclusion of build status files as inputs is controlled by the —[no]stamp flag. Stamped targets are not rebuilt unless their dependencies change.
Default value is 0 since the majority of js_run_binary targets in a build graph typically do not use build status files and including them for all js_run_binary actions whenever --stamp is set would result in invalidating the entire graph and would prevent cache hits. Stamping is typically done in terminal targets when building release artifacts and stamp should typically be set explicitly in these targets to -1 so it is enabled when the --stamp flag is set.When stamping is enabled, an additional two environment variables will be set for the action:
  • BAZEL_STABLE_STATUS_FILE
  • BAZEL_VOLATILE_STATUS_FILE
These files can be read and parsed by the action, for example to pass some values to a bundler.
patch_node_fs
unknown
default:"True"
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.
allow_execroot_entry_point_with_no_copy_data_to_bin
unknown
default:"False"
Turn off validation that the js_binary tool has copy_data_to_bin set to True when use_execroot_entry_point is set to True.See use_execroot_entry_point doc for more info.
use_default_shell_env
unknown
default:"False"
Passed to the underlying ctx.actions.run.May introduce non-determinism when True; use with care! See e.g. https://github.com/bazelbuild/bazel/issues/4912Refer to https://bazel.build/rules/lib/builtins/actions#run for more details.
kwargs
unknown
Additional arguments