npm / npm/rfcs

[RRFC] Add flag for running NPM commands in transitive dependencies

Open
#548 20 comments 54 reactions 0 assignees View on GitHub

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 -w flag
    • 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 run script 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.