|
| 1 | +# RFC: Add `preunpack` life cycle script |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +Add a `preunpack` life cycle script that runs before anything else. |
| 6 | + |
| 7 | +## Motivation |
| 8 | + |
| 9 | +npm v7 introduced a new order of running the `preinstall` script, where it runs **after** dependencies are installed, breaking backward compatibility with packages expecting to run a script **before** dependencies are installed. |
| 10 | + |
| 11 | +By introducing a new life cycle script that will run first in the execution order, we can give a path forward to packages that require a script to run **before** dependencies are installed. |
| 12 | + |
| 13 | +Use cases: |
| 14 | + |
| 15 | +* Handling authentication for private registries with short-lived tokens (i.e., AWS, GCP, Azure) |
| 16 | +* Generating workspaces from gRPC proto files before workspaces and dependencies get evaluated. |
| 17 | + |
| 18 | +## Detailed Explanation |
| 19 | + |
| 20 | +A `preunpack` life cycle script that is **first** in execution order: |
| 21 | + |
| 22 | +* Runs on local `npm install` without any arguments |
| 23 | +* Runs on non-local `npm install` (from a package installing the package) |
| 24 | + |
| 25 | +Example usage in the case of handling authentication for AWS CodeArtifact: |
| 26 | + |
| 27 | +```json |
| 28 | +{ |
| 29 | + "name": "my-app", |
| 30 | + "version": "1.0.0", |
| 31 | + "description": "A sample application consuming a private scoped npm package", |
| 32 | + "main": "index.js", |
| 33 | + "scripts": { |
| 34 | + "preunpack": "npm run co:login", |
| 35 | + "co:login": "aws codeartifact login --tool npm --repository my-repo --domain my-domain" |
| 36 | + }, |
| 37 | + "dependencies": { |
| 38 | + "@myorg/my-package": "^1.0.0" |
| 39 | + } |
| 40 | +} |
| 41 | +``` |
| 42 | + |
| 43 | +When running `npm install`, the `npm run co:login` will be run before any dependencies are installed. |
| 44 | + |
| 45 | +## Rationale and Alternatives |
| 46 | + |
| 47 | +### Implement a separate top level "events" field |
| 48 | + |
| 49 | +The idea here would be to implement a top-level "events" field to keep the current behavior of "scripts" while providing a better implementation elsewhere as described in [this comment](https://github.com/npm/cli/issues/2660#issuecomment-794415767). |
| 50 | + |
| 51 | +This approach would undoubtedly address the use cases outlined above, but the scope may be too large when we need a quicker stop-gap for the interim. |
| 52 | + |
| 53 | +### Revert back to the `preinstall` functionality from versions before v7 |
| 54 | + |
| 55 | +See [Unresolved Questions and Bikeshedding](#unresolved-questions-and-bikeshedding). |
| 56 | + |
| 57 | +## Implementation |
| 58 | + |
| 59 | +<!-- 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. --> |
| 60 | + |
| 61 | +<!-- 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 --> |
| 62 | + |
| 63 | +## Prior Art |
| 64 | + |
| 65 | +* npm v6 |
| 66 | + |
| 67 | +## Unresolved Questions and Bikeshedding |
| 68 | + |
| 69 | +* Are there any security implications with this approach? |
| 70 | +* Are we sure we don't want to revert back to the `preinstall` functionality of npm v6? |
| 71 | + |
| 72 | +<!-- THIS SECTION SHOULD BE REMOVED BEFORE RATIFICATION --> |
0 commit comments