You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: support for multi-linked first party dependencies
Adds the ability to link first party deps to subdirectories and adds a new `links` to `yarn_install` and `npm_install` which simplifies linking first party deps into `yarn_install` and `npm_install` managed `node_modules` trees.
The first release of the multi-linker, which landed in 3.2.0, supported linking only 3rd party deps to subdirectories.
------------------------------
This new feature is enabled by new `npm_link` which can add a `LinkablePackageInfo` to any target.
If a target already provides a `LinkablePackageInfo`, it provides a new `LinkablePackageInfo` with a new provided values for `package_path` and `package_name` which informs the linker into which `${package_path}/node_modules/${package_name}` folder to link the package into.
For example, given
```
lib_a/BUILD.bazel:
js_library(
name = "lib_a",
srcs = [
"index.js",
"package.json",
],
package_name = "@somescope/lib-a"
)
```
which makes `//lib_a:lib_a` link to the root node_modules at `node_modules/@somescope/lib-a`
`npm_link` can be used to create a new `lib_a` target that links elsewhere:
```
sub/BUILD.bazel:
npm_link(
name = "lib_a",
target = "//lib_a",
package_path = "sub",
package_name = "@somescope/lib-a",
)
```
which makes `//sub:lib_a` linked to `sub/node_modules/@somescope/lib-a`.
Note: a target may depend on both `//lib_a:lib_a` and `//sub:lib_a` in its `deps` and the linker will link the library to both
`node_modules/@somescope/lib-a` and `sub/node_modules/@somescope/lib-a` respectively.
Alternately, `npm_link` can add a `LinkablePackageInfo` provider to a target that doesn't yet have a `package_name` associated with it,
For example,
```
lib_b/BUILD.bazel:
js_library(
name = "lib_b",
srcs = [
"index.js",
"package.json",
],
)
```
```
sub/BUILD.bazel:
npm_link(
name = "lib_b",
target = "//lib_b",
package_path = "sub",
package_name = "@somescope/lib-b",
)
```
which makes `//sub:lib_b` linked to `sub/node_modules/@somescope/lib-b` while `//lib_b:lib_b` is not linked at all.
The linked target can be of any type, including a simple filegroup. For example,
```
lib_c/BUILD.bazel:
filegroup(
name = "lib_c",
srcs = [
"index.js",
"package.json",
],
)
```
```
sub/BUILD.bazel:
npm_link(
name = "lib_c",
target = "//lib_c",
package_path = "sub",
package_name = "@somescope/lib-c",
)
```
which makes `//sub:lib_c` linked to `sub/node_modules/@somescope/lib-c` while `//lib_c:lib_c` is not linked at all.
------------------------------
With the above abilities, we've also added syntactical sugar to `yarn_install` and `npm_install` which uses `npm_link` under the hood.
For example, given a `sub/package.json` we can define its `yarn_install` as,
```
WORKSPACE:
yarn_install(
name = “@sub_npm_deps”,
package_json = "//sub:package.json",
package_path = "sub",
links = {
"@somescope/lib-a": "//lib_a:lib_a",
"@somescope/lib-b": "//lib_b:lib_b",
}
)
```
which generates two `npm_link` under the hood:
```
@sub_npm_deps//@somescope/lib-a:BUILD.bazel:
npm_link(
name = "lib-a",
target = "//lib_a:lib_a",
package_path = "sub",
package_name = "@somescope/lib-a",
)
```
```
@sub_npm_deps//@somescope/lib-b:BUILD.bazel:
npm_link(
name = "lib-b",
target = "//lib_b:lib_b",
package_path = "sub",
package_name = "@somescope/lib-b",
)
```
which are both linked to `sub/node_modules` (`sub/node_modules/@somescope/lib-a` and `sub/node_modules/@somescope/lib-b` respectively).
This allows the downstream syntactical sugar of depending on first party deps by their package names from the external workspace they are "linked" to.
```
sub/BUILD.bazel:
nodejs_binary(
name = "bin",
entry_point = "bin.js",
data = [
"bin.js"
"@sub_npm_deps//@somescope/lib-a",
"@sub_npm_deps//@somescope/lib-b",
]
)
```
and those deps will be available to the application in `sub/node_modules` where you would expect them to be if they had been defined in the `sub/package.json` itself using yarn workspaces outside of bazel.
`sub/bin.js` can then require those libs with,
```
const liba = require('@somescope/lib-a')
const libb = require('@somescope/lib-b')
```
and those will be resolved to `sub/node_modules/@somescope/lib-a/index.js` and `sub/node_modules/@somescope/lib-b/index.js` with standard node_modules resolution.
0 commit comments