[RRFC] Multi-app Monorepo Support
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 777
- Forks
- 267
- PR merge metrics
- No merged PRs in 30d
Description
Before Opening Please...
- Search for an existing/duplicate RRFC which might be relevant to your RRFC
Motivation ("The Why")
Please see detailed description in https://github.com/npm/rfcs/discussions/462, but tl;dr I'd like npm to "natively" support installing a package workspace's npm pack'd artifact into an app workspace's local node_modules folder for production deployment without a bunch of extra prerelease/registry rigmarole. In a sense treat the monorepo/workspace root as a kind of ephemeral local registry
Example
A monorepo with three workspaces, two apps "a" and "b", one package "c". Apps "a" and "b" depend on package "c", and are deployed to different locations (Docker, AWS Lambda, Google Cloud Functions, etc). Following best practices, minimizing build tooling, and wanting to ship a lean, production-only, app artifact, I'd like to an app structure like this (the dist folder is just meant to represent some production-ready code, this is just to show a folder structure that expresses the relationship between packages):
$ tree apps/a --dirsfirst
apps/a
├── dist
├── node_modules
│ └── @my
│ └── c
│ ├── dist
│ └── package.json
└── package.json
With this structure I'd zip the apps/a folder and push it to AWS, or COPY it into a Docker image in my Dockerfile, etc.
How
Current Behaviour
This structure can be roughly achieved by running these commands:
npm pack -w @my/c
npm pack -w @my/c --pack-destination=apps/a
npm i my-c-1.0.0.tgz -w @my/a
rm my-c-1.0.0.tgz apps/a/my-c-1.0.0.tgz
Note:
I'm not sure why it's necessary to pack it twice, but something about running npm i my.tgz -w @my/a needs the tarball to exist in both the root and the workspace. Maybe a separate bug about resolving install paths when -w is set?
Also worth noting this changes apps/a/package.json's "@my/c" dependency from "^1.0.0" to "file:my-c-1.0.0.tgz" which I have to immediately undo in order to maintain the dev-time hoisted dependency functionality I want.
Desired Behaviour
Allow a way to specify that npm install and/or npm ci should look to the workspaces in the current monorepo before reaching out to a registry. If a match is found call npm pack on that workspace and "serve" the resultant tarball (or its contents). Some suggestions for what this'd look like in the cli:
npm i --only=prod --prefer-workspaces -w @my/anpm i --only=prod --prefer-local -w @my/anpm i --only=prod --registry=file:///. -w @my/a- this one's definitely the weirdest, it'd require npm to detect that the "registry" at that file URI is a monorepo/workspace-root, but has the advantage of not adding a new flag to the cli, and maybe being configurable via .npmrc?
It should work for npm ci as well.
References
- Initial discussion: https://github.com/npm/rfcs/discussions/462
- Why I think Lerna doesn't already solve this use case: https://github.com/npm/rfcs/discussions/462#discussioncomment-1380842
- Why I think file/folder references are also unsatisfactory: https://github.com/npm/rfcs/discussions/462#discussioncomment-1380544
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 with the linked RFC discussion 462 and compare its context with the current-behavior command sequence in this issue. Evaluate the proposed workspace-preference approaches for both npm install and npm ci, including packaging and dependency-path effects. Done means an agreed RFC direction with resolved behavior and CLI or configuration semantics.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- cli, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100