Files
Zoltan Kochan 3f6516caeb docs: correct the guides from migration to workspaces (#17249)
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.
2026-10-23 14:22:57 +02:00

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.