Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Run prepare Scripts for Linked Bundled Dependencies #481

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
76 changes: 76 additions & 0 deletions accepted/0000-prepare-linked-bundled-deps-during-pack.md
@@ -0,0 +1,76 @@
# Run `prepare` Scripts for Linked Bundled Dependencies

## Summary

Following discussion on [#477](https://github.com/npm/rfcs/issues/477) and previously on [#463](https://github.com/npm/rfcs/issues/463), workspaces that depend on sibling workspaces via the `file:` protocol (a.k.a. linked or symlinked dependencies) should run the sibling workspaces' `prepare` scripts as part of the depend-_ing_ workspace's `pack` operation when those sibling dependencies are also specified as bundle/d dependencies (e.g. their "built" output should make it into the packed workspace's tarball).

## Motivation

It's common for workspaces in a monorepo to depend on one another. Calling `npm pack` on a workspace should automatically run the `prepare` script of any linked and bundled dependencies so that the produced tarball will have consistent and correct contents without a bunch of extra wiring.

## Detailed Explanation

`app-a` and `pkg-b` are workspaces in a monorepo. `app-a` depends on `pkg-b` and lists it as a `bundledDependency` because `app-a` is expected to be distributed as a Node app somewhere (AWS Lambda, Docker, etc.) where it should be deployed along with its production dependencies. `pkg-b` is not published to a registry for reasons, and is written in a language or standard that must be compiled or transpiled to be runnable in Node (TypeScript, ES2049, etc.).

Assuming `app-a`s package.json contains this:

```json
{
"name": "app-a",
"version": "1.0.0",
"dependencies": {
"pkg-b": "file:../pkg-b"
},
"bundleDependencies": ["pkg-b"]
}
```

… and `pkg-b`'s package.json contains this:

```json
{
"name": "pkg-b",
"version": "1.0.0",
"scripts": {
"prepare": "tsc"
}
}
```

… with the appropriate tsconfig.json, .npmignore, and index.ts in `pkg-b`, running `cd app-a ; npm i --package-lock=false ; npm pack` should produce a tarball with contents like:

```sh
app-a
├── node_modules
│ └── pkg-b
│ ├── index.js
│ └── package.json
└── package.json
```

## Rationale and Alternatives

This functionality is possible today, but requires the package being packed to explicitly call the `prepare` scripts of each of its linked and bundled dependencies.

It's also possible to achieve the same end result by publishing the bundled dependencies to a registry, but for a package that's expected to have utility only within the context of other workspaces in a monorepo this adds a bunch of bureacracy for not much benefit.

## Implementation

Need help with this part.

> {{Give a high-level overview of implementation requirements and concerns. Be specific about areas of code that need to change, and what their potential effects are. Discuss which repositories and sub-components will be affected, and what its overall code effect might be.}}
>
> {{THIS SECTION IS REQUIRED FOR RATIFICATION -- you can skip it if you don't know the technical details when first submitting the proposal, but it must be there before it's accepted}}

## Prior Art

- Related to a forthcoming PR about workspace/dependency layout from @ljharb
- Discussed at [#478](https://github.com/npm/rfcs/issues/478)

## Unresolved Questions and Bikeshedding

I don't think there's anything here, but leaving it for now in case I've missed/forgotten something.

> {{Write about any arbitrary decisions that need to be made (syntax, colors, formatting, minor UX decisions), and any questions for the proposal that have not been answered.}}
>
> {{THIS SECTION SHOULD BE REMOVED BEFORE RATIFICATION}}