Files
pnpm/fetching/fetcher-base/src/index.ts
Zoltan Kochan 421317c31a feat!: skip npm, npx, and corepack when installing node runtime (#11325)
## Summary

- pnpm installing a Node.js runtime (`node@runtime:<ver>`, `pnpm env use`, `pnpm runtime set node`) no longer extracts the bundled `npm`, `npx`, and `corepack`. These make up ~2,800 of ~5,800 files in a typical Node.js archive, so skipping them materially reduces hashing, CAS writes, SQLite index inserts, and import/link work.
- Users who still need `npm` can install it as a separate package.

## How

A new optional `ignoreFilePattern` (regex source string, serializable across the worker boundary) threads through `FetchOptions` → `tarball-fetcher` → `@pnpm/worker` → `cafs.addFilesFromTarball`. `cafs.addFilesFromTarball` now accepts a per-call ignore on top of the existing cafs-level `ignoreFile`; the two are combined.

`@pnpm/fetching.binary-fetcher` defines the Node-specific regex and applies it when `opts.pkg.name === 'node'`:

- Tarball path: sets `ignoreFilePattern`.
- Windows zip path: new `ignoreEntry?: RegExp` on `AssetInfo`; `extractZipToTarget` strips the `basename/` prefix and skips matching entries before `zip.extractEntryTo`.

`@pnpm/engine.runtime.node-resolver`'s `getNodeBinsForCurrentOS` drops `npm`/`npx` so pnpm no longer creates shims for bins that no longer exist.

## Breaking change

Shipping in v11. After this lands, `pnpm runtime set node` / `node@runtime:<version>` no longer puts `npm`, `npx`, or `corepack` on `$PATH`. Scripts that call them directly will need to install npm separately.
2026-04-21 13:44:48 +02:00

85 lines
2.1 KiB
TypeScript

import type {
BinaryResolution,
DirectoryResolution,
GitResolution,
Resolution,
} from '@pnpm/resolving.resolver-base'
import type { Cafs, FilesMap } from '@pnpm/store.cafs-types'
import type { AllowBuild, BundledManifest, DependencyManifest } from '@pnpm/types'
export interface PkgNameVersion {
name?: string
version?: string
}
export interface FetchOptions {
allowBuild?: AllowBuild
filesIndexFile: string
lockfileDir: string
onStart?: (totalSize: number | null, attempt: number) => void
onProgress?: (downloaded: number) => void
readManifest?: boolean
pkg: PkgNameVersion
appendManifest?: DependencyManifest
/**
* Regex source (compatible with `new RegExp(pattern)`) matching file paths inside the
* downloaded archive that should be skipped during extraction. Honored by tarball fetchers.
*/
ignoreFilePattern?: string
}
export type FetchFunction<FetcherResolution = Resolution, Options = FetchOptions, Result = FetchResult> = (
cafs: Cafs,
resolution: FetcherResolution,
opts: Options
) => Promise<Result>
export interface FetchResult {
local?: boolean
manifest?: BundledManifest
filesMap: FilesMap
requiresBuild: boolean
integrity?: string
}
export interface GitFetcherOptions {
allowBuild?: AllowBuild
readManifest?: boolean
filesIndexFile: string
pkg?: PkgNameVersion
}
export interface GitFetcherResult {
filesMap: FilesMap
manifest?: BundledManifest
requiresBuild: boolean
}
export type GitFetcher = FetchFunction<GitResolution, GitFetcherOptions, GitFetcherResult>
export type BinaryFetcher = FetchFunction<BinaryResolution>
export interface DirectoryFetcherOptions {
lockfileDir: string
readManifest?: boolean
}
export interface DirectoryFetcherResult {
local: true
filesMap: FilesMap
packageImportMethod: 'hardlink'
manifest?: DependencyManifest
requiresBuild: boolean
}
export type DirectoryFetcher = FetchFunction<DirectoryResolution, DirectoryFetcherOptions, DirectoryFetcherResult>
export interface Fetchers {
localTarball: FetchFunction
remoteTarball: FetchFunction
gitHostedTarball: FetchFunction
directory: DirectoryFetcher
git: GitFetcher
binary: BinaryFetcher
}