[RRFC] Add flag for running NPM commands in transitive dependencies
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 777
- Forks
- 267
- PR merge metrics
- No merged PRs in 30d
Description
Motivation ("The Why")
There are many tools to manage multiple NPM packages in a concise and user friendly way. For a long time the front runner for those were Lerna and Yarn Workspaces.
NPM mono repos tools usually have two main features:
- Installing node_modules across an entire tree of dependencies and symlinking any dependencies in the tree that are found to be local to the mono repo
- Running commands across those packages
With the release of NPM 7 and NPM workspace npm itself came much closer to having the features needed out of the box to run a mono repo. This was great because Lerna has since been largely abandoned and the Yarn ecosystem was fragmented with the release of v2. However, NPM workspaces is lacking in the ability to run commands across transitive dependencies.
There are other mono repo tools gaining popularity like TurboRepo and NX but those have their own toolchains and features to consider, I think it would be preferred for NPM to support this out of the box.
It is important to note that this feature was expected to function this way by enough users that two issues https://github.com/npm/cli/issues/3413 and https://github.com/npm/cli/issues/4139 both considered this a bug and not a new feature.
Example
Having this feature would allow for mono repo tooling to run exclusively with npm something that comes out of the box with Node.js. Not requiring any other toolchains or special workflows.
How
Current Behaviour
Take this repo for example:
https://github.com/zgriesinger/monorepo
In it we have a npm workspace with frontends, apis, cli tools and shared packages.
If I pull the app down and:
npm i
npm run build -w @zgriesinger/service-a
I'll be met with errors since the @zgriesinger/logger package has not been built (but it has been symlinked)
If I know the transitive dependencies of service-a that are local to the repo I can do this to get the build working
npm run build -w @zgriesinger/logger
npm run build -w @zgriesinger/service-a
This is why most mono repos have to keep some other toolchain around, with lerna there is the --include-dependencies flag that will automatically run the build for @zgriesinger/logger
Desired Behaviour
The desired behavior of the npm cli would be to include a --include-dependencies flag similar to lerna.
The functionality/algorithm of this flag would be as follows:
- Read dependencies of targeted workspace with
-wflag- If dependencies includes any internal to the mono repo, read them and start from the beginning (Including matching versions)
- If not, run the desired
npm runscript in that package, and return up to run the command in the parent package
The result should be in the example above:
npm run build -w @zgriesinger/service-a
-> Runs build in @zgriesinger/logger
-> On succes runs build in @zgriesinger/service-a
References
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the proposed behavior and examples in this RFC, then review referenced issues #3413 and #4139 and the linked monorepo example. Clarify how workspace dependency traversal and command ordering should work, including matching versions and failures. Done means an agreed npm CLI design for an include-dependencies flag.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100