aspect-build / aspect-build/rules_js
[FR]: link outside WORKSPACE for dependencies during local development (~= `pnpm link`)
- Dominant language
- Starlark
- Stars
- 378
- Forks
- 183
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 32
Description
### What is the current behavior?
Currently, `rules_js` fetches packages from either:
1. A remote location (https://registry.nodejs.org/..., git://github.com/...) with the Bazel downloader
2. The user workspace (//pkg/left-pad), which requires the package to be pulled into the workspace and its dependencies readable by `npm_translate_lock`.
Attempts to link outside the Bazel workspace to an NPM package located elsewhere on-disk get rejected with
[invalid link_package outside of the WORKSPACE](https://github.com/aspect-build/rules_js/blob/fd156d1bb159d2982f0fa4bc798a2bc618db2a11/npm/private/npm_translate_lock_generate.bzl#L97-L104).
### Describe the feature
The [npm link](https://docs.npmjs.com/cli/v9/commands/npm-link) workflow is pretty common in the node community, as it allows a dev to modify a third-party package and use it without having to vendor that package.
As a contrived example motivation (replace `left-pad` with any other package):
1. I've found a pathological case in `left-pad` performance that my application highlights
2. I'd like to contribute a fix back to upstream `left-pad`. While working on that fix, I want to use the locally-changed copy in my application as a sort of "real world" gut-check in addition to the `left-pad` test suite. Just to make sure my pathological case is indeed getting fixed.
3. I don't want to vendor `left-pad` for any number of reasons:
1. `left-pad` has a complicated/obscure build system that makes it non-trivial to vendor and build with `rules_js`.
2. `left-pad` takes bugfixes incredibly fast, so my vendored copy would only exist for a few hours after my PR goes out.
In the current state, there appears to be no way to build `left-pad` in a separate directory and use it in my `rules_js`-built package(s).
With vanilla `pnpm link` (or `npm link` or …), the workflow is roughly:
1. `pnpm --dir ~/bitbucket.org/my-org/my-app link ~/github.com/left-pad/left-pad` to use a custom `left-pad`
6. Change and rebuild `left-pad`.
7. Change and rebuild `my-app`. It includes my `left-pad` changes.
Ideally, the workflow would be pretty similar under Bazel + rules_js. For local development it feels reasonable to break hermeticity, akin to `npm_translate_lock`'s current `use_home_npmrc`), but I'd be happy to add an extra flag or two to achieve this.
-----
Relevant slack conversation: https://bazelbuild.slack.com/archives/CEZUUKQ6P/p1689358470077099
Contributor guide
Research direction
Start with npm/private/npm_translate_lock_generate.bzl, especially the validation linked from the issue, and trace how npm_translate_lock handles workspace and remote package sources. Compare that flow with the described pnpm link workflow. Done means a package built outside the Bazel WORKSPACE can be used during local development and rebuilt changes are visible to the consuming application.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- build-system
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100