pnpm 11.2

У версії pnpm 11.2 реалізовано експериментальну опцію, яка дозволяє використовувати pacquet (портування pnpm на Rust) як бекенд для встановлення, розширює залежності конфігурації для встановлення одного рівня optionalDependencies (тож шаблон платформних бінарних файлів esbuild/swc працює також для залежностей конфігурації), підключає давно задокументований прапорець pnpm login --scope та виводить записи часу виконання (Node.js, Deno, Bun) у pnpm outdated та pnpm update --interactive.

Незначні зміни#

Експериментально: pacquet як внутрішній рушій встановлення#

Додавання @pnpm/pacquet (версії pnpm на Rust) до configDependencies у pnpm-workspace.yaml тепер делегує етап матеріалізації pnpm install двійковому файлу pacquet. pnpm все ще відповідає за вирішення залежностей; pacquet лише витягує та імпортує їх із щойно записаного файлу блокування. Це ознайомча версія рушія встановлення на Rust, яка вмикається за бажанням, див. #11723.

Щоб налаштувати pacquet у проєкті, виконайте:

pnpm add @pnpm/pacquet --config

Ви побачите зміни у pnpm-workspace.yaml та pnpm-lock.yaml, які потрібно зафіксувати. Якщо у вас виникнуть будь-які проблеми з pacquet, будь ласка, повідомте нам про це у створенному вами тікеті на GitHub.

optionalDependencies для залежностей конфігурації#

Залежності конфігурації тепер розвʼязують і встановлюють один рівень optionalDependencies, оголошених самою залежністю конфігурації, із застосуванням фільтрації за платформою (os / cpu / libc) під час встановлення. Це відкриває шлях до шаблону в стилі esbuild/swc, коли пакунок постачає специфічні для платформи двійкові файли через optionalDependencies — залежність конфігурації тепер може робити те саме й мати відповідний двійковий файл, привʼязаний символьним посиланням поруч із собою у глобальному віртуальному сховищі, тому require('pkg-platform-arch') зсередини залежності конфігурації розвʼязується правильно.

Файл блокування env фіксує всі варіанти платформи незалежно від платформи хоста, тому він залишається сумісним на різних машинах. Кожен запис в optionalDependencies конфігурації залежностей повинен вказувати точну версію, діапазони та теги відхиляються для збереження відтворюваності інсталяції.

pnpm login --scope#

Давно задокументований прапорець pnpm login --scope <scope> тепер реалізовано. Область дії нормалізується (додається початковий символ @, якщо він відсутній; порожні значення ігноруються), і зіставлення @<scope>:registry=<registry> записується у файл автентифікації pnpm разом із токеном автентифікації. Подальші встановлення пакунків @<scope>/* після цього спрямовуватимуться до обраного реєстру. Раніше задокументований прапорець викликав помилку Unknown option: 'scope'. Див. #11716.

Середовища виконання в outdated та update --interactive#

pnpm outdated та pnpm update --interactive тепер повідомляють про середовища виконання Node.js, Deno та Bun, які встановлені як залежності проєкту (специфікатори runtime:). Раніше вони просто ігнорувалися.

Зміни в патчах#

  • Fixed cafile=<relative-path> in .npmrc being read from the wrong directory when pnpm is invoked from a different cwd (e.g. pnpm --dir <project> install from a CI wrapper or monorepo script). The path is now resolved against the directory of the .npmrc that declared it, not process.cwd(). Before this fix, the install proceeded without the configured CA and the user only saw TLS errors against a private registry with no log line tying back to the wrongly resolved path #11624.
  • Fixed config.registry getting a trailing slash appended when registry is set in .npmrc and no registries.default is provided by pnpm-workspace.yaml.
  • Fixed global add/update to handle minimumReleaseAge policy violations instead of surfacing an internal resolver guardrail error.
  • Fixed two crashes with injectWorkspacePackages: true when the lockfile has been pruned (e.g. by turbo prune --docker): a Cannot use 'in' operator to search for 'directory' in undefined from peer-dependency-variant injected snapshots whose base packages: entry had been dropped, and an ERR_PNPM_ENOENT on node_modules/.bin/<tool> after prepare / postinstall re-imported each injected workspace package.
  • Fixed pnpm login and pnpm logout ignoring registries.default from pnpm-workspace.yaml #10099.
  • Fixed the minimumReleaseAge (publishedBy) maturity shortcut to be inclusive at the cutoff. Previously, abbreviated metadata whose modified field equalled the cutoff fell off the fast path and triggered a full-metadata re-fetch (or a MISSING_TIME error when full metadata wasn't permitted).
  • Honor publishConfig.access when publishing packages.

11.2.1#

  • Mark optional subdependency snapshots of config dependencies with optional: true in the env lockfile, matching how optional dependencies are recorded elsewhere in pnpm-lock.yaml. Previously, snapshots for the platform-specific subdeps pulled in via a config dep's optionalDependencies were written as empty objects.
  • Fixed pickRegistryForPackage returning the wrong registry for an unscoped npm: alias under a scoped local name. A manifest entry like "@private/foo": "npm:lodash@^1" was routing the lodash fetch through registries["@private"], even though lodash is unscoped.
  • Don't print Installing config dependencies... when config dependencies are already installed and nothing needs to be fetched, re-linked, or removed.

11.2.2#

  • When the install engine is delegated to pacquet via configDependencies, the user's CLI flags passed to pnpm install (e.g. --no-runtime, --prod, --dev, --no-optional, --node-linker, --cpu / --os / --libc, --offline, --prefer-offline) are now forwarded to pacquet's install subcommand verbatim. Previously pacquet was invoked with a fixed argument list, so flags like --no-runtime were silently dropped. Flag forwarding is gated on the command being install / i; add, update, and dedupe still don't forward (their flag surface doesn't line up with pacquet's install).
  • Fixed pnpm up (and pnpm add / pnpm remove) failing with pacquet_package_manager::outdated_lockfile when pacquet is declared in configDependencies. pnpm now passes --ignore-manifest-check to pacquet so its --frozen-lockfile check doesn't fire against the (pre-mutation) package.json pnpm hasn't written yet #11797.