pnpm 11.0
pnpm 11 вже тут! У цьому випуску посилено стандартні налаштування безпеки, запроваджені протягом усього циклу v10, скасовано використання npm CLI як альтернативного варіанту для публікації на користь власної реалізації, замінено індекс сховища у форматі JSON для кожного пакета на єдину базу даних SQLite, а також ізольовано глобальні інсталяції, щоб вони більше не впливали одна на одну.
Він також вимагає Node.js 22 або новішу версію — сам pnpm тепер є чистим ESM.
Оновлюєтесь з v10? Перегляньте інструкцію Міграція з v10 до v11. Більшість змін у налаштуваннях є механічними, і їх можна застосувати за допомогою кодмода pnpm-v10-to-v11.
Основні моменти#
- Потрібен Node.js 22+. Підтримку Node 18, 19, 20 та 21 припинено. Окремий виконуваний файл потребує glibc 2.27 або новішої версії.
- Захист ланцюжка постачання стандартно увімкнений.
minimumReleaseAgeзазвичай має значення1440(1 день), аblockExoticSubdeps—true. allowBuildsзамінює застарілі налаштування залежностей збірки.onlyBuiltDependencies,onlyBuiltDependenciesFile,neverBuiltDependencies,ignoredBuiltDependenciesтаignoreDepScriptsвидалено.- Глобальні встановлення є ізольованими і в стандартному режимі використовують глобальне віртуальне сховище. Кожна команда
pnpm add -gстворює свою власну теку з власними файламиpackage.json,node_modulesта файлом блокування. - Новий індекс сховища на базі SQLite (сховище v11) із вбудованими даними конфігурацій та шістнадцятковими ключами для меншої кількості системних викликів та швидшого встановлення.
- Власний процес публікації.
pnpm publish,login,logout,view,deprecate,unpublish,dist-tagтаversionбільше не передають керування до npm CLI. .npmrcпризначений тільки для авторизації/реєстрів. Інші налаштування мають перебувати вpnpm-workspace.yamlабо в новому глобальномуconfig.yaml. Змінні середовища використовують префіксpnpm_config_*.
Істотні зміни#
Вимоги#
- Припиняється підтримка Node.js 18, 19, 20 та 21.
- Тепер pnpm постачається виключно як чистий ESM.
- Окремий виконуваний файл потребує glibc 2.27+.
Безпека та стандартні налаштування збірки#
Деякі стандартні значення були змінені на більш безпечні:
| Налаштування | Нове стандартне значення |
|---|---|
minimumReleaseAge | 1440 (1 день) |
minimumReleaseAgeStrict | false |
blockExoticSubdeps | true |
strictDepBuilds | true |
optimisticRepeatInstall | true |
verifyDepsBeforeRun | install |
Нещодавно опубліковані пакунки не будуть використовуватися, доки не мине принаймні 1 день з моменту їх опублікування. Щоб відмовитися від цього, встановіть значення minimumReleaseAge: 0 у файлі pnpm-workspace.yaml.
allowBuilds замінює старі налаштування збірки#
onlyBuiltDependencies, onlyBuiltDependenciesFile, neverBuiltDependencies, ignoredBuiltDependencies та ignoreDepScripts були видалені. Використовуйте натомість allowBuilds — відповідність шаблонів імен пакетів булевим значенням:
До:
onlyBuiltDependencies:
- electron
onlyBuiltDependenciesFile: "allowed-builds.json"
neverBuiltDependencies:
- core-js
ignoredBuiltDependencies:
- esbuild
Після:
allowBuilds:
electron: true
core-js: false
esbuild: false
Також видалено: allowNonAppliedPatches (використовуйте allowUnusedPatches) та ignorePatchFailures (тепер у разі невдачі застосування патчів генеруються помилки).
.npmrc призначений тільки для авторизації/реєстрів#
pnpm більше не зчитує налаштування, які не стосуються авторизації, із .npmrc. Конфігурація розділена на дві категорії:
- Налаштування реєстру та авторизації — файли INI (
.npmrc, глобальний файлrc,~/.config/pnpm/auth.ini). - Налаштування, специфічні для pnpm — файли YAML (
pnpm-workspace.yaml, новий глобальний файл~/.config/pnpm/config.yaml).
Інші повʼязані зміни:
-
pnpm більше не читає змінні середовища npm_config_. Натомість використовуйте
pnpm_config_*(наприклад,pnpm_config_registry). -
pnpm більше не зчитує поле
pnpmвpackage.json. -
pnpm більше не зчитує глобальні налаштування npm з файлу
$PREFIX/etc/npmrc. -
Налаштування мережі (
httpProxy,httpsProxy,noProxy,localAddress,strictSsl,gitShallowHosts) тепер записуються у файлиconfig.yaml/pnpm-workspace.yaml(їх все ще можна прочитати з файлу.npmrcдля полегшення міграції). -
Новий параметр
registriesуpnpm-workspace.yamlзамінює рядки@scope:registry=:registries: default: https://registry.npmjs.org/ "@my-org": https://private.example.com/ "@internal": https://nexus.corp.com/ -
Індивідуальний для кожного проєкту
.npmrcзамінено наpackageConfigsуpnpm-workspace.yaml:packages: - "packages/project-1" - "packages/project-2" packageConfigs: "project-1": saveExact: true "project-2": savePrefix: "~"
Вбудований процес публікації, без використання npm CLI#
Команди, які раніше делегувалися в npm CLI, були або перероблені на рівні ядра, або вилучені.
Наново реалізовано команди: publish, view (info, show, v), login (adduser), logout, deprecate, unpublish, dist-tag, version, search, star/unstar/stars, whoami, ping, docs/home.
Видалено (тепер видає помилку "не реалізовано") команди: access, bugs, edit, issues, owner, prefix, profile, pkg, repo, set-script, team, token, xmas.
Кілька нотаток щодо нової вбудованої комманди pnpm publish:
- Змінна оточення OTP тепер називається
PNPM_CONFIG_OTP(раніше булаNPM_CONFIG_OTP). - Якщо реєстр запитує OTP, а його не вказано, pnpm запитає його інтерактивно.
- Вебавтентифікація показує URL-адресу та QR-код, який можна сканувати.
Команда pnpm audit використовує точку доступу bulk для групових повідомлень#
Застарілі точки доступу /-/npm/v1/security/audits{,/quick} більше не підтримуються реєстром. Команда pnpm audit тепер викликає /-/npm/v1/security/advisories/bulk, яка не повертає ідентифікатори CVE — тому фільтрування на основі CVE було замінено на фільтрування на основі GHSA:
auditConfig.ignoreCves→auditConfig.ignoreGhsaspnpm audit --ignore <id>та--ignore-unfixableчитають та пишуть GHSA
Для виконання міграції замініть кожен запис CVE-YYYY-NNNNN у розділі ignoreCves на відповідний запис GHSA-xxxx-xxxx-xxxx (який можна побачити у стовпці More info команди pnpm audit) та перемістіть його до розділу ignoreGhsas.
Ізольовані глобальні встановлення з глобальним віртуальним сховищем#
pnpm add -g <pkg> та pnx тепер використовують глобальне віртуальне сховище, і кожне встановлення отримує власну ізольовану теку в {pnpmHomeDir}/global/v11/{hash}/ зі своїм package.json, node_modules/ та файлом блокування. Це запобігає взаємному впливу глобальних пакунків через конфлікти залежностей між одноранговими компонентами, підняття змін або розбіжності у версіях.
pnpm remove -g <pkg>видаляє всю групу встановлення, що містить цей пакунок.pnpm update -g [pkg]повторно встановлює пакунок у нову ізольовану теку.pnpm list -gсканує ізольовані теки.pnpm install -g(без аргументів) більше не підтримується — використовуйтеpnpm add -g <pkg>.
Глобально встановлені бінарні файли тепер знаходяться в теці bin всередині PNPM_HOME (а не безпосередньо в PNPM_HOME), тому внутрішні теки на кшталт global/ та store/ не засмічують автодоповнення оболонки. Запустіть pnpm setup після оновлення, щоб оновити конфігурацію вашої оболонки.
Команда pnpm link також зазнала змін: тепер приймаються лише відносні або абсолютні шляхи, параметр --global було вилучено (використовуйте pnpm add -g .), а pnpm link без аргументів більше не підтримується.
Інші видалення#
-
pnpm server. -
useNodeVersionтаexecutionEnv.nodeVersion— використовуйтеdevEngines.runtime/engines.runtime. -
hooks.fetchers— замінено новим полемfetchersу pnpmfile. -
managePackageManagerVersions,packageManagerStrict, таpackageManagerStrictVersion. Усі вони раніше визначали поведінкуonFailзастарілого поляpackageManager; нове налаштуванняpmOnFailтепер обʼєднує їх усі в собі:Видалено Змінено на managePackageManagerVersions: truepmOnFail: download(стандартно)managePackageManagerVersions: falsepmOnFail: ignorepackageManagerStrict: falsepmOnFail: warnpackageManagerStrictVersion: truepmOnFail: errorCOREPACK_ENABLE_STRICT=0pmOnFail: warn
Нові команди#
| Команда | Що вона робить |
|---|---|
pnpm ci | Виконує pnpm clean, а потім pnpm install --frozen-lockfile. Псевдоніми: clean-install, ic, install-clean. |
pnpm clean | Видаляє node_modules з усіх проєктів робочого простору. З --lockfile також видаляє pnpm-lock.yaml. |
pnpm sbom | Генерує специфікацію програмного забезпечення (SBOM) у форматі JSON для CycloneDX 1.7 або SPDX 2.3. |
pnpm peers check | Повідомляє про невідповідності або відсутність однорангових залежностей у файлі блокування. |
pnpm runtime set | Встановлює середовище виконання; pnpm env use тепер є застарілим. |
pnpm docs / home | Відкриває головну сторінку пакунка. |
pnpm ping | Здійснює запит до реєстру для оцінки його доступності. |
pnpm with | Запускає pnpm конкретної (або поточної) версії для одного виклику, ігноруючи обмеження поля packageManager. |
pnpm pack-app | Перетворює модуль CommonJS на самостійний виконуваний файл для однієї або кількох цільових платформ за допомогою Node.js SEA. |
Разом із безпосередньо реалізованими заново командами, переліченими в розділі "Вбудований процес публікації" вище, а також короткими псевдонімами pn для pnpm та pnx для pnpx/pnpm dlx.
pnpm audit --fix=update#
Усуває вразливості шляхом оновлення пакунків у lockfile замість додавання перевизначень. Для більш гнучкого контролю новий прапорець --interactive / -i дозволяє вибрати, які саме загрози безпеки потрібно виправити:
pnpm audit --fix=update --interactive
Команда pnpm audit --fix також додає мінімальну версію з виправленнями для кожного повідомлення про вразливість до параметра minimumReleaseAgeExclude у файлі pnpm-workspace.yaml, завдяки чому виправлення безпеки можна встановлювати, не чекаючи на закінчення терміну minimumReleaseAge.
ESM pnpmfiles#
Тепер файли pnpmfile можна створювати як ESM, використовуючи розширення .mjs. Якщо файл .pnpmfile.mjs існує, він має пріоритет над .pnpmfile.cjs, і завантажується лише один із них.
Сховище v11#
Сховище було перероблено з урахуванням двох принципів: скоротити кількість запитів на читання та зменшити кількість системних викликів.
- Індекс пакунків тепер являє собою єдину базу даних SQLite у файлі
$STORE/index.db(зі значеннями у форматі MessagePack та у режимі WAL для паралельного доступу) замість мільйонів файлів JSON у теці$STORE/index/. Пакунки, відсутні у новому індексі будуть повторно завантажуватися за потреби. - Зведений маніфест (назва, версія, бінарні файли, рушії, скрипти тощо) зберігається безпосередньо в індексі пкакунків, що усуває потребу читати
package.jsonіз CAS під час розвʼязання залежностей та встановлення. - У записах індексу зберігаються шестнадцяткові хеші замість повних рядків перевірки цілісності (
<algo>-<digest>), а алгоритм хешування записується один раз для кожного файлу, а не для кожного запису. Це дозволяє уникнути конвертації base64 → hex при кожному пошуку шляху в CAS. - Коли увімкнено глобальне віртуальне сховище, пакунки, для яких заборонено збірку (і які транзитивно не залежать від пакунків, де вона дозволена), отримують хеші, що не включають назву рушія (платформу, архітектуру, основну версію Node.js). ~95 % пакунків GVS тепер без проблем витримують оновлення Node.js та зміни архітектури без необхідності повторного імпорту.
Продуктивність#
Багато дрібних покращень разом дають помітно швидше встановлення:
undiciзамінюєnode-fetchдля всіх HTTP-запитів, привносячи Happy Eyeballs (подвійний стек), покращений keep-alive та оптимізований глобальний диспетчер.- Завантаження архівів із відомим розміром заздалегідь виділяють памʼять, щоб уникнути накладних витрат на подвійне копіювання.
- Кеш метаданих тепер у форматі NDJSON, із використанням
If-Modified-Sinceдля умовних запитів. - Перевірки
minimumReleaseAgeвикористовують точку доступу зі скороченими метаданими, щоб завантажувати менше. - Файли CAS записуються безпосередньо за їхнім шляхом, що визначається за змістом, а не через тимчасовий файл із подальшим перейменуванням — це дозволяє заощадити близько 30 тис. системних викликів перейменування під час кожного «холодного» встановлення.
- Під час імпортування в
node_modulesтека staging зникає. - Операції з рядками з використанням «гарячих шляхів» у CAS були оптимізовані, а функція
gunzipSyncтепер працює з більшим розміром блоків, що дозволяє зменшити кількість виділень буферів під час розпакування архівів tar. - Під час повторних встановлень GVS із кешу надлишкове внутрішнє лінкування пропускається, якщо жодних пакунків не було додано.
Більш компактні встановлення середовища виконання#
Встановлення Node.js через node@runtime:<version> (включаючи pnpm env use та pnpm runtime set node) більше не розпаковує вбудовані npm, npx та corepack з архіву Node.js. Це скорочує приблизно половину файлів, які pnpm має хешувати, записувати в CAS та лінкувати. Якщо вам усе ще потрібен npm, встановіть його як окремий пакунок.
Інші суттєві зміни#
-
Чистіший вивід скриптів.
pnpmтепер виводить$ command(в stderr, щоб stdout залишався придатним для конвеєрів) замість> pkg@version stage path\n> command. Назва та шлях до проєкту показуються лише під час виконання в іншій теці. -
Проблеми з прямими (peer) залежностями більше не показуються у вигляді дерева під час встановлення — pnpm пропонує запустити
pnpm peers checkдля їх перегляду. -
Скрипти життєвого циклу більше не отримують змінні оточення
npm_config_*з конфігурації pnpm; встановлюються лише загальновідомі змінніnpm_*, як у Yarn. -
pnpm initзаписуєdevEngines.packageManagerзамістьpackageManager, якщо увімкненоinit-package-manager, а стандартне значенняtypeтепер"module". -
devEngines.packageManagerтепер підтримує діапазони версій; знайдена версія зберігається вpnpm-lock.yamlі використовується повторно, якщо вона все ще відповідає діапазону. -
dedupePeers— нове налаштування, яке використовує суфікси лише з версією (name@version) замість повних шляхів залежностей, що усуває вкладені суфікси на зразок(foo@1.0.0(bar@2.0.0))для проєктів із великою кількістю рекурсивних peer-залежностей. -
pnpm approve-buildsтепер приймає позиційні аргументи для неінтерактивного використання; додайте префікс!перед назвою, щоб відхилити її. -
Приховані скрипти — скрипти, що починаються з
., можуть викликатися лише з інших скриптів і не зʼявляються уpnpm run. -
-Fє новим коротким псевдонімом для--filter. -
Короткі прапорці для
pnpm add—-dтепер означає--save-dev,-p—--save-prod,-o—--save-optional,-e—--save-exact(тільки всерединіpnpm add). -
virtualStoreOnlyнаповнює віртуальне сховище без створення символьних посилань імпортера, підняття залежностей, створення посилань на бінарні файли чи запуску скриптів життєвого циклу. Корисно для попереднього наповнення сховища під час збирання в Nix.pnpm fetchвикористовує цей режим внутрішньо. -
nodeDownloadMirrorsуpnpm-workspace.yamlзамінює параметрnode-mirror:<channel>в.npmrc:nodeDownloadMirrors: release: https://my-mirror.example.com/download/release/ -
Залежності конфігурації тепер встановлюються в
{storeDir}/links/і додаються як символьні посилання вnode_modules/.pnpm-config/, тому вони використовуються спільно між проєктами, які мають теж сховище. Знайдені версії та хеші цілісності перенесені з файлуpnpm-workspace.yamlдо окремого документаpnpm-lock.yaml; міграція проєктів зі старими вбудованими хешами відбувається автоматично.
Оновлення#
Дивіться повний посібник «Міграція з v10 на v11» для отримання кодмоду та інструкцій щодо ручного доопрацювання. Коротка версія:
- Оновіть ваш CI та середовища розробки до Node.js 22+ перед оновленням.
- Перемістить налаштування pnpm з
.npmrcдоpnpm-workspace.yaml(або глобального~/.config/pnpm/config.yaml). - Перенесіть
onlyBuiltDependenciesта подібні параметри доallowBuilds. - Перенесіть
auditConfig.ignoreCvesдоauditConfig.ignoreGhsas. - Після встановлення v11, запустіть
pnpm setupдля оновлення вашої оболонки, щоб нова текаbinбула вPATH.
Повний перелік змін у журналі змін. Якщо щось, на що ви покладалися, відсутнє або зламане, будь ласка, створіть тікет за адресою github.com/pnpm/pnpm/issues.