Skip to main content

nodejs_binary

A runnable Node.js script, executed with the toolchain's Node runtime and no custom loaders. The [dir] sub-target, present unless main is a directory run with entry_point (below), is one directory holding a node_modules composed from the transitive nodejs_library packages and the packages of the third-party trees, main and srcs beside it at their short paths (distinct files staging to the same path fail, as does one under node_modules when any package is composed), and a package.json at its root: the one in srcs, or else {"name": <target name>, "private": true, "version": "0.0.0"}, for tools that look for the project root beside node_modules (the name is lowercased and cut to 214 characters, with characters npm rejects replaced by -). When library, deps, a third-party tree, a resources dict or package_style = "standalone" is involved, the staged main runs from [dir], so Node's own resolution finds every package, for import, require, worker threads and child node processes alike. Otherwise, main runs at its original path and files it imports via relative paths must be listed in srcs to be declared as build inputs. NODE_PATH is never set; one set in env is passed through. The default output is the launcher: a command_alias trampoline for the target platform that runs the toolchain's node with node_args, the entry and args, and sets env; $(location) of the target runs it. DefaultInfo and RunInfo are the providers command_alias returns: RunInfo runs the same command, without the trampoline when env is empty. For an in-place target without srcs, the trampoline and RunInfo match those of command_alias(exe = <toolchain node>, args = node_args + [<entry>] + args, env = env, resources = resources). resources are files and directories the program reads at run time: a list stages each at its short path in [dir], a dict at its key. When main runs in place, a list's entries stay at their original paths as hidden inputs, as command_alias's resources do; a dict always stages. [dir] stages a list even when a file main runs in place, so two list entries with the same short path, or an entry at the path of a distinct main or srcs file, fail either way. main may be a directory, such as a filegroup or a genrule with out = ".". With entry_point (and no library), node runs <main>/<entry_point> in place, with no [dir]; a main ending in .js, .mjs, .cjs, .ts, .mts, .cts or .json is a file and fails. srcs, deps, node_modules, a resources dict and package_style = "standalone" are rejected. Without entry_point, node runs main itself, which for a directory means its package.json main or index.js. Deps must be loadable as regular node_modules packages: each package's package.json governs whether it is CommonJS or an ES module, and TypeScript must be compiled to JavaScript before it is packaged. Each nodejs_library package is staged without its .d.ts/.d.mts/.d.cts files and their maps (the library's [runtime]), because Node's type stripping refuses declarations under node_modules. Transitive deps' package directories must be unique, as for nodejs_library. A deps entry that is not a nodejs_library is a data dep: it must have exactly one default output, which is staged at the dep's package path in [dir]. A directory output, such as a filegroup's, keeps its files at their repository-relative paths (for a test that reads another package's files); a single file becomes the file at that path. A data dep cannot be a nodejs_node_modules tree, a runnable target or in the root package, and its path must not be, contain or sit inside another data dep's or a staged main, srcs or resources entry's path. node_modules, when unset, takes the third-party trees of library and deps (see nodejs_library's node_modules); a list of nodejs_node_modules targets replaces them, and [] means none. Third-party packages are composed one by one as installed (they keep their .d.ts files; dot entries such as .bin are dropped): a package that two sources provide fails the build and names both, and exclude on a nodejs_node_modules drops packages. library, when set, runs a file from inside a nodejs_library's package instead of main (a library with only deps or node_modules stages none and fails here): entry_point names the file relative to the package root (e.g. "main.js"; a relative /-separated path with no : and no . or .. segments), and defaults to the library's bin attribute when it has exactly one, else its main attribute; entries set only in the library's package_json or prebuilt manifest are not read, so such a library needs entry_point. main/srcs cannot be combined with library, and entry_point requires it or a directory main. package_style is "inplace" (the default) or "standalone". standalone always stages, adds the toolchain's node_dist binary to the staged directory as node (node.exe on Windows), and replaces the default output with a zip of that directory under a top-level directory named after the target (which therefore cannot contain /), for hosts without Node. The package runs as <name>/node <name>/<main>, or with library, as <name>/node <name>/node_modules/<dir>/<entry_point>, where <dir> is the library's out, or its package_name when out is unset; args, node_args, env and any flags or env the toolchain's node wrapper adds are not applied there.

Function Signature​

def nodejs_binary(
*,
name: str,
default_target_platform: None | str = None,
target_compatible_with: list[str] = [],
compatible_with: list[str] = [],
exec_compatible_with: list[str] = [],
visibility: list[str | target_name_glob] = [],
within_view: list[str | target_name_glob] = ["PUBLIC"],
metadata: OpaqueMetadata = {},
tests: list[str] = [],
modifiers: OpaqueMetadata = [],
_nodejs_toolchain: str = "gh_facebook_buck2_shims_meta//:nodejs",
_target_os_type: str = "prelude//os_lookup/targets:os_lookup",
_zip_file_toolchain: str = "gh_facebook_buck2_shims_meta//:zip_file",
args: list[str] = [],
contacts: list[str] = [],
deps: list[str] = [],
entry_point: None | str = None,
env: dict[str, str] = {},
labels: list[str] = [],
library: None | str = None,
main: None | str = None,
node_args: list[str] = [],
node_modules: None | list[str] = None,
package_style: str = "inplace",
resources: list[str] | dict[str, str] = [],
srcs: list[str] = [],
) -> None

Parameters​

  • name: (required)

    name of the target

  • default_target_platform: (defaults to: None)

    specifies the default target platform, used when no platforms are specified on the command line

  • target_compatible_with: (defaults to: [])

    a list of constraints that are required to be satisfied for this target to be compatible with a configuration

  • compatible_with: (defaults to: [])

    a list of constraints that are required to be satisfied for this target to be compatible with a configuration

  • exec_compatible_with: (defaults to: [])

    a list of constraints that are required to be satisfied for this target to be compatible with an execution platform

  • visibility: (defaults to: [])

    a list of visibility patterns restricting what targets can depend on this one

  • within_view: (defaults to: ["PUBLIC"])

    a list of visibility patterns restricting what this target can depend on

  • metadata: (defaults to: {})

    a key-value map of metadata associated with this target

  • tests: (defaults to: [])

    a list of targets that provide tests for this one

  • modifiers: (defaults to: [])

    an array of modifiers associated with this target

  • contacts: (defaults to: [])

    A list of organizational contacts for this rule. These could be individuals who you would contact in the event of a failure or other issue with the rule.

    contacts = [ 'Joe Sixpack', 'Erika Mustermann' ]
  • labels: (defaults to: [])

    Set of arbitrary strings which allow you to annotate a build rule with tags that can be searched for over an entire dependency tree using buck query().