npm_link_package rule

Rules

Defines a node package that is linked into a node_modules tree as a direct dependency.

This is used in co-ordination with the npm_link_package_store rule that links into the node_modules/.apsect_rules_js virtual store with a pnpm style symlinked node_modules output tree.

The term "package" is defined at https://nodejs.org/docs/latest-v16.x/api/packages.html

See https://pnpm.io/symlinked-node-modules-structure for more information on the symlinked node_modules structure. Npm may also support a symlinked node_modules structure called "Isolated mode" in the future: https://github.com/npm/rfcs/blob/main/accepted/0042-isolated-mode.md.

Example usage (generated)

load("@aspect_rules_js//npm/private:npm_link_package.bzl", "npm_link_package_direct")

npm_link_package_direct(
    # A unique name for this target.
    name = "",
    # The npm_link_package target to link as a direct dependency.
    src = "",
)

A unique name for this target.

The package name to link to.

If unset, the package name of the src npm_link_package_store is used. If set, takes precendance over the package name in the src npm_link_package_store.

The npm_link_package target to link as a direct dependency.


Defines a node package that is linked into a node_modules tree.

The node package is linked with a pnpm style symlinked node_modules output tree.

The term "package" is defined at https://nodejs.org/docs/latest-v16.x/api/packages.html

See https://pnpm.io/symlinked-node-modules-structure for more information on the symlinked node_modules structure. Npm may also support a symlinked node_modules structure called "Isolated mode" in the future: https://github.com/npm/rfcs/blob/main/accepted/0042-isolated-mode.md.

Example usage (generated)

load("@aspect_rules_js//npm/private:npm_link_package.bzl", "npm_link_package_store")

npm_link_package_store(
    # A unique name for this target.
    name = "",
    # A npm_package target or or any other target that provides a NpmPackageInfo
    src = "",
)

A unique name for this target.

Other node packages store link targets one depends on mapped to the name to link them under in this packages deps.

This should include all modules the program may need at runtime.

You can find all the package store link targets in your repository with

bazel query ... | grep :.aspect_rules_js | grep -v /dir | grep -v /pkg | grep -v /ref

Package store link targets names for 3rd party packages that come from npm_translate_lock start with .aspect_rules_js/ then the name passed to the npm_link_all_packages macro (typically 'node_modules') followed by /<package>/<version> where package is the package name (including @scope segment if any) and version is the specific version of the package that comes from the pnpm-lock.yaml file.

For example,

//:.aspect_rules_js/node_modules/cliui/7.0.4

The version may include peer dep(s),

//:.aspect_rules_js/node_modules/debug/4.3.4_supports-color@8.1.1

It could be also be a url based version,

//:.aspect_rules_js/node_modules/debug/github.com/ngokevin/debug/9742c5f383a6f8046241920156236ade8ec30d53

Package store link targets names for 3rd party package that come directly from an npm_import start with .aspect_rules_js/ then the name passed to the npm_import's npm_link_imported_package macro (typically 'node_modules') followed by /<package>/<version> where package matches the package attribute in the npm_import of the package and version matches the version attribute.

For example,

//:.aspect_rules_js/node_modules/cliui/7.0.4

Package store link targets names for 1st party packages automatically linked by npm_link_all_packages using workspaces will follow the same pattern as 3rd party packages with the version typically defaulting to "0.0.0".

For example,

//:.aspect_rules_js/node_modules/@mycorp/mylib/0.0.0

Package store link targets names for 1st party packages manually linked with npm_link_package start with .aspect_rules_js/ followed by the name passed to the npm_link_package.

For example,

//:.aspect_rules_js/node_modules/@mycorp/mylib

In typical usage, a node.js program sometimes requires modules which were never declared as dependencies. This pattern is typically used when the program has conditional behavior that is enabled when the module is found (like a plugin) but the program also runs without the dependency.

This is possible because node.js doesn't enforce the dependencies are sound. All files under node_modules are available to any program. In contrast, Bazel makes it possible to make builds hermetic, which means that all dependencies of a program must be declared when running in Bazel's sandbox.

The package name to link to.

If unset, the package name in the NpmPackageInfo src must be set. If set, takes precendance over the package name in the NpmPackageInfo src.

A npm_package target or or any other target that provides a NpmPackageInfo.

The package version being linked.

If unset, the package version in the NpmPackageInfo src must be set. If set, takes precendance over the package version in the NpmPackageInfo src.


Macros and Functions

"Links an npm package to the virtual store if in the root package and directly to node_modules if direct is True.

When called at the root_package, a virtual store target is generated named "link__{bazelified_name}__store".

When linking direct, a "{name}" target is generated which consists of the direct node_modules link and transitively its virtual store link and the virtual store links of the transitive closure of deps.

When linking direct, "{name}/dir" filegroup is also generated that refers to a directory artifact can be used to access the package directory for creating entry points or accessing files in the package.

Example usage (generated)

load("@aspect_rules_js//npm/private:npm_link_package.bzl", "npm_link_package")

npm_link_package(
    # The name of the direct link target to create (if linked directly)
    name = "",
)

The name of the direct link target to create (if linked directly). For first-party deps linked across a workspace, the name must match in all packages being linked as it is used to derive the virtual store link target name.

the root package where the node_modules virtual store is linked to

whether or not to link a direct dependency in this package For 3rd party deps fetched with an npm_import, direct may not be specified if link_packages is set on the npm_import.

the npm_package target to link; may only to be specified when linking in the root package

list of npm_link_package_store; may only to be specified when linking in the root package

whether or not to fail if this is called in a package that is not the root package and with direct false

whether or not to automatically add a manual tag to the generated targets Links tagged "manual" dy default is desirable so that they are not built by bazel build ... if they are unused downstream. For 3rd party deps, this is particularly important so that 3rd party deps are not fetched at all unless they are used.

the visibility of the generated targets

see attributes of npm_link_package_store rule


Example usage (generated)

load("@aspect_rules_js//npm/private:npm_link_package.bzl", "npm_link_package_direct_lib")

npm_link_package_direct_lib.implementation(
    ctx = None,
)

Example usage (generated)

load("@aspect_rules_js//npm/private:npm_link_package.bzl", "npm_link_package_store_lib")

npm_link_package_store_lib.implementation(
    ctx = None,
)