Part of pnpm/tasks#191. Wrong claims: - npmrc: `ca` defaults to the system trust store (v12) or the Node.js CA set (v11), not "the npm CA certificate". - pnpm-cli: `--config.<key>` does not populate `npm_config_*` for scripts (v11 and v12). - pnpm-vs-npm, package-sources: `file:` directories are copied into the virtual store and installed; only `link:` is a symlink. - pnpmfile: `importPackage` is removed in v12; changing the pnpmfile re-resolves, so the lockfile need not be deleted (v11 and v12). - scripts: list every environment variable a script receives (v11 and v12), and the full set of built-ins a script can shadow. - supply-chain-security: build scripts are blocked by `allowBuilds` and `strictDepBuilds`, and `blockExoticSubdeps` is on by default. - workspaces: pnpm has built-in release management (v11 and v12). Missing: - npmrc: `NODE_EXTRA_CA_CERTS`. - pnpm-cli: `--workspace-packages`, `-y`, and the `NO_COLOR`, `pnpm_config_*`, `PNPM_HOME`, `PNPM_SHIM_BYPASS` variables. - package_json: a `packageManager` section, `@<scope>:registry` in the `publishConfig` list, the built-in injected-deps sync. - pnpmfile: `beforePacking(pkg, dir, context)`, TL;DR rows for `updateConfig`, `preResolution`, `finders`, the `.cjs` fallback. - typescript: `addMissingPeerTypes`; uninstall: cache, state, and config directories; scripts: project lifecycle stages; workspaces: a minimal `packages` example and live sync while a script runs. - sidebar: `only-allow-pnpm`, `production`, and `cli/cache`. Clarity and duplication: - One home for git-dependency preparation (package-managers), Python index rules (registries), finders (finders.md). - motivation, symlinked-node-modules-structure: files are hard-linked or cloned; package directories are real directories; Node resolves symlinks to real paths. - podman copies the lockfile and workspace manifest; webcontainers leads with `pmOnFail: ignore`; task priority applies within a concurrency group; logos get alt text; store-loader spells out CAS. - using-changesets workflow uses the same action versions and Node.js 24 as the CI guide (v11 and v12). Stale history on v12 pages: - Removed "Added in" markers for v11 and older, and rewrote "Since v11..." and pnpm 10/11 narration as current behavior. Review follow-up: the script environment notes say which npm_config_* keys are filtered (auth, scope registry, per-registry) and that pnpm sets npm_config_user_agent and npm_config_node_gyp; a string `bin` sets npm_package_bin; NODE_EXTRA_CA_CERTS adds to whichever CA set applies; the v10 codemod command notes pnpx; motivation notes that pnpm copies files when neither hard links nor clones work; production says `pnpm fetch` reads the lockfile, not the package manifests.
89 lines
3.7 KiB
Markdown
89 lines
3.7 KiB
Markdown
---
|
|
id: scripts
|
|
title: Scripts
|
|
---
|
|
|
|
How pnpm handles the `scripts` field of `package.json`.
|
|
|
|
## Hidden scripts
|
|
|
|
Added in: v11.0.0
|
|
|
|
Scripts with names starting with `.` are hidden. They cannot be run directly via `pnpm run` and are omitted from the `pnpm run` listing. Hidden scripts can only be called from other scripts.
|
|
|
|
```json title="package.json"
|
|
{
|
|
"scripts": {
|
|
".helper": "echo 'I am hidden'",
|
|
"build": "pnpm run .helper && tsc"
|
|
}
|
|
}
|
|
```
|
|
|
|
In this example, `pnpm run .helper` would fail, but `pnpm run build` would succeed because `.helper` is called from another script.
|
|
|
|
## Environment variables
|
|
|
|
pnpm sets the following environment variables during lifecycle script execution:
|
|
|
|
- `npm_package_name`: the package name
|
|
- `npm_package_version`: the package version
|
|
- `npm_package_config_*`, `npm_package_engines_*`, `npm_package_bin_*`: the
|
|
`config`, `engines`, and `bin` fields of the manifest, one variable per entry
|
|
(for example, `npm_package_config_port`). A string `bin` sets `npm_package_bin`.
|
|
- `npm_package_json`: the path to the package's `package.json`
|
|
- `npm_lifecycle_event`: the name of the running script (e.g., `postinstall`)
|
|
- `npm_lifecycle_script`: the command of the running script
|
|
- `npm_node_execpath` and `NODE`: the path to the Node.js executable
|
|
- `npm_execpath`: the path to the running pnpm
|
|
- `npm_config_user_agent`: pnpm's user agent string
|
|
- `npm_config_node_gyp`: the path to the bundled `node-gyp`, unless the
|
|
environment already sets it
|
|
- `INIT_CWD`: the directory where pnpm was started
|
|
- `PNPM_SCRIPT_SRC_DIR`: the directory of the package whose script runs
|
|
- `TMPDIR`: `node_modules/.tmp` in the package, unless
|
|
[`unsafePerm`](./settings/build.md#unsafeperm) is `true`
|
|
|
|
:::note
|
|
|
|
Apart from the variables above, pnpm does not set `npm_config_*` variables from
|
|
its configuration. Other `npm_config_*` variables in the environment reach the
|
|
script unchanged, except auth, scope-registry, and per-registry settings (names
|
|
starting with `_`, `/`, or `@`, or containing `:_`).
|
|
|
|
:::
|
|
|
|
## Built-in command and script name conflicts
|
|
|
|
Added in: v11.0.0
|
|
|
|
The following built-in commands prefer user scripts: `clean`, `setup`, `deploy`, and `rebuild`. If your `package.json` defines a script with one of these names, `pnpm <name>` will execute the script instead of the built-in command.
|
|
|
|
To force the built-in command, use [`pnpm pm <name>`](./cli/pm.md).
|
|
|
|
## Lifecycle scripts
|
|
|
|
### `pnpm:devPreinstall`
|
|
|
|
Runs when `pnpm install` runs in the project itself, including in CI. It does not run when the package is installed as a dependency of another project.
|
|
|
|
Runs before any dependency is installed.
|
|
|
|
This script is executed only when set in the root project's `package.json`.
|
|
|
|
Since v11.28.0, installs that skip `devDependencies`, such as `pnpm install --prod`, do not run it.
|
|
|
|
### `preinstall` of the root project
|
|
|
|
Since v11.28.0, the root project's `preinstall` script runs before dependencies are resolved and linked. A guard such as `npx only-allow pnpm` can therefore stop the install before pnpm populates `node_modules`.
|
|
|
|
### `prepare`
|
|
|
|
The root project's `prepare` script runs after `pnpm install`. It is skipped, since v11.28.0, by installs that skip `devDependencies` (such as `pnpm install --prod`), by `pnpm install` given package arguments, and for the project that [`pnpm deploy`](./cli/deploy.md) deploys.
|
|
|
|
### Uninstall scripts
|
|
|
|
Added in: v11.28.0
|
|
|
|
[`pnpm remove`](./cli/remove.md) runs the project's own `preuninstall`, `uninstall`, and `postuninstall` scripts. `preuninstall` and `uninstall` run before dependencies are unlinked, and a failure in either aborts the removal. `postuninstall` runs after unlinking completes. The [`ignoreScripts`](./settings/build.md#ignorescripts) setting and `--lockfile-only` skip all three.
|