Перейти до основного змісту
Версія: 10.x

Package manifest (package.json, package.json5, package.yaml)

Файл маніфесту пакунка. Він містить усі метадані пакунка, включно із залежностями, назвою, автором тощо. Це стандарт, який зберігається у всіх основних менеджерах пакунків Node.js, включаючи pnpm.

In addition to the traditional package.json format, pnpm also supports package.json5 (via json5) and package.yaml (via js-yaml).

engines

Ви можете вказати версію Node і pnpm, на якій працює ваше програмне забезпечення:

{
"engines": {
"node": ">=10",
"pnpm": ">=3"
}
}

Під час локальної розробки pnpm завжди завершить роботу з повідомленням про помилку, якщо його версія не збігається з версією, вказаною у полі engines.

Якщо користувач не встановив прапорець конфігурації engine-stric (див. .npmrc), це поле є лише рекомендаційним і показуватиме попередження лише тоді, коли ваш пакунок встановлено як залежність.

dependenciesMeta

Додаткова метаінформація, що використовується для залежностей, оголошених всередині dependencies, optionDependencies та devDependencies.

dependenciesMeta.*.injected

Якщо для залежності, яка є пакунком локального робочого простору, встановлено значення true, цей пакунок буде встановлено шляхом створення копії з жорстким посиланням у віртуальному сховищі (node_modules/.pnpm).

Якщо цей параметр встановлено у false або не встановлено, залежність буде встановлено шляхом створення символічного посилання node_modules, яке вказуватиме на теку з кодом пакунка у робочій області. Це стандартний спосіб, оскільки він швидший і гарантує, що будь-які зміни в залежності будуть негайно помітні її споживачам.

Наприклад, припустимо, що наступний package.json є пакунком локального робочого простору:

{
"name": "card",
"dependencies": {
"button": "workspace:1.0.0"
}
}

Залежність button зазвичай встановлюється шляхом створення символічного посилання у теці node_modules теки card, яке вказує на теку розробки для button.

Але що, якщо button вказує react у своїх peerDependencies? Якщо всі проєкти в монорепо використовують однакову версію react, то проблеми немає. Але що робити, якщо button вимагає card, який використовує react@16 і form, який використовує react@17? Зазвичай вам потрібно вибрати одну версію react і вказати її за допомогою devDependencies з button. Створення символічних посилань не дає можливості задовольнити залежність react різними споживачами, такими як card та form, по-різному.

Поле injected розвʼязує цю проблему, встановлюючи копії button у віртуальному сховищі з жорсткими посиланнями. Щоб досягти цього, package.json для card можна сконфігурувати наступним чином:

{
"name": "card",
"dependencies": {
"button": "workspace:1.0.0",
"react": "16"
},
"dependenciesMeta": {
"button": {
"injected": true
}
}
}

Тоді як package.json для form можна було б налаштувати наступним чином:

{
"name": "form",
"dependencies": {
"button": "workspace:1.0.0",
"react": "17"
},
"dependenciesMeta": {
"button": {
"injected": true
}
}
}

З цими змінами ми говоримо, що button є "injected dependency" від card і form. Коли button імпортує react, він перетвориться на react@16 в контексті card, але перетвориться на react@17 в контексті form.

Оскільки інʼєкційні залежності створюють копії теки з вихідним кодом своєї робочої області, ці копії необхідно якось оновлювати щоразу, коли код модифікується; інакше новий стан не буде відображено для споживачів. Якщо ви збираєте декілька проєктів за допомогою команди типу pnpm --recursive run build, це оновлення має відбуватися після того, як буде зібрано кожен пакунок, але до того, як буде зібрано його споживачів. У простих випадках це можна зробити повторним викликом pnpm install, можливо, за допомогою сценарію життєвого циклу package.json, наприклад, "prepare": "pnpm run build" для перезбірки цього проєкту. Сторонні інструменти, такі як pnpm-sync та pnpm-sync-dependencies-meta-injected надають більш надійне та ефективне рішення для оновлення інʼєкційних залежностей, а також підтримку режиму спостереження.

peerDependenciesMeta

У цьому полі перелічено деяку додаткову інформацію, повʼязану із залежностями, переліченими у полі peerDependencies.

peerDependenciesMeta.*.optional

Якщо цей параметр встановлено у true, вибрану пряму залежність буде позначено менеджером пакунків як необовʼязкову. Таким чином, якщо споживач пропустить її, це більше не буде вважатися помилкою.

Наприклад:

{
"peerDependencies": {
"foo": "1"
},
"peerDependenciesMeta": {
"foo": {
"optional": true
},
"bar": {
"optional": true
}
}
}

Зауважте, що навіть якщо bar не було вказано у peerDependencies, він позначений як необовʼязковий. Таким чином, pnpm буде вважати, що будь-яка версія bar є прийнятною. Втім, foo є необовʼязковим, але лише для необхідної специфікації версії.

publishConfig

Можна перевизначити деякі поля в маніфесті до того, як пакунок буде запаковано. Наступні поля можуть бути перевизначені:

Щоб перевизначити поле, додайте версію для публікації до publishConfig.

Наприклад, наступний package.json:

{
"name": "foo",
"version": "1.0.0",
"main": "src/index.ts",
"publishConfig": {
"main": "lib/index.js",
"typings": "lib/index.d.ts"
}
}

Буде опубліковано як:

{
"name": "foo",
"version": "1.0.0",
"main": "lib/index.js",
"typings": "lib/index.d.ts"
}

publishConfig.executableFiles

Стандартно, з міркувань переносимості, жодні файли, окрім тих, що перелічено у полі bin, не буде позначено як виконувані у результуючому архіві пакунків. Поле executableFiles дозволяє вам оголошувати додаткові поля, які повинні мати прапорець виконуваності (+x), навіть якщо вони не доступні безпосередньо через поле bin.

{
"publishConfig": {
"executableFiles": [
"./dist/shim.js"
]
}
}

publishConfig.directory

Ви також можете використовувати поле publishConfig.directory для налаштування опублікованої підтеки відносно поточного package.json.

Очікується, що у зазначеній теці міститиметься модифікована версія поточного пакунка (зазвичай за допомогою сторонніх засобів збирання).

У цьому прикладі тека "dist" повинна містити package.json

{
"name": "foo",
"version": "1.0.0",
"publishConfig": {
"directory": "dist"
}
}

publishConfig.linkDirectory

  • Стандартно: true
  • Тип: Boolean

Якщо встановлено значення true, під час локальної розробки проєкт буде зʼєднано з текою publishConfig.directory.

Наприклад:

{
"name": "foo",
"version": "1.0.0",
"publishConfig": {
"directory": "dist",
"linkDirectory": true
}
}

pnpm.overrides

У цьому полі ви можете вказати pnpm перевизначити будь-яку залежність у графі залежностей. Це корисно для того, щоб змусити всі ваші пакунки використовувати одну версію залежності, перенести виправлення, замінити залежність форком або видалити невикористовувану залежність.

Зверніть увагу, що поле перевизначень можна встановити лише у корені проєкту.

Приклад поля "pnpm"."overrides":

{
"pnpm": {
"overrides": {
"foo": "^1.0.0",
"quux": "npm:@myorg/quux@^1.0.0",
"bar@^2.1.0": "3.0.0",
"qar@1>zoo": "2"
}
}
}

Ви можете вказати пакунок, до якого належить перевизначена залежність, відокремивши селектор пакунка від селектора залежності символом ">", наприклад, qar@1>zoo перевизначить лише залежність zoo пакунка qar@1, а не будь-які інші залежності.

Перевизначення можна визначити як посилання на специфікацію прямої залежності. Це досягається шляхом додавання до імені залежності префікса $:

{
"dependencies": {
"foo": "^1.0.0"
},
"pnpm": {
"overrides": {
"foo": "$foo"
}
}
}

Пакунок, на який посилаються, не обовʼязково повинен збігатися з пакунком, на який посилається перевизначений:

{
"dependencies": {
"foo": "^1.0.0"
},
"pnpm": {
"overrides": {
"bar": "$foo"
}
}
}

Якщо ви вважаєте, що використання певного пакунка не потребує однієї з його залежностей, ви можете вилучити її за допомогою -. Наприклад, якщо пакунок foo@1.0.0 потребує великого пакунка з назвою bar для функції, яку ви не використовуєте, вилучення цього пакунка може скоротити час встановлення:

{
"pnpm": {
"overrides": {
"foo@1.0.0>bar": "-"
}
}
}

Ця можливість особливо корисна для optionalDependencies, де більшість необовʼязкових пакунків можна безпечно пропустити.

pnpm.packageExtensions

Поля packageExtensions надають можливість розширити наявні визначення пакунків додатковою інформацією. Наприклад, якщо react-redux повинен мати react-dom у своїх peerDependencies, але не має, можна виправити react-redux за допомогою packageExtensions:

{
"pnpm": {
"packageExtensions": {
"react-redux": {
"peerDependencies": {
"react-dom": "*"
}
}
}
}
}

Ключами у packageExtensions є назви пакунків або назви пакунків і діапазони semver, тому можна виправити лише деякі версії пакунків:

{
"pnpm": {
"packageExtensions": {
"react-redux@1": {
"peerDependencies": {
"react-dom": "*"
}
}
}
}
}

Наступні поля можна розширити за допомогою packageExtensions: dependencies, optionalDependencies, peerDependencies і peerDependenciesMeta.

Більший приклад:

{
"pnpm": {
"packageExtensions": {
"express@1": {
"optionalDependencies": {
"typescript": "2"
}
},
"fork-ts-checker-webpack-plugin": {
"dependencies": {
"@babel/core": "1"
},
"peerDependencies": {
"eslint": ">= 6"
},
"peerDependenciesMeta": {
"eslint": {
"optional": true
}
}
}
}
}
}
підказка

Разом з Yarn ми підтримуємо базу даних packageExtensions для виправлення несправних пакунків в екосистемі. Якщо ви використовуєте packageExtensions, подумайте про те, щоб надіслати PR і внести ваше розширення до бази даних @yarnpkg/extensions.

pnpm.peerDependencyRules

pnpm.peerDependencyRules.ignoreMissing

pnpm не виводитиме попередження про відсутні у цьому списку прямі залежності.

Наприклад, у наступній конфігурації pnpm не виводитиме попередження, якщо залежність потребує react, але react не встановлено:

{
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": ["react"]
}
}
}

Також можна використовувати шаблони назв пакунків:

{
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": ["@babel/*", "@eslint/*"]
}
}
}

pnpm.peerDependencyRules.allowedVersions

Попередження про незадоволені залежності не буде виведено для залежностей із вказаного діапазону.

Наприклад, якщо у вас є залежності, які потребують react@16, але ви знаєте, що вони чудово працюють з react@17, то ви можете використовувати наступну конфігурацію:

{
"pnpm": {
"peerDependencyRules": {
"allowedVersions": {
"react": "17"
}
}
}
}

Це скаже pnpm, що будь-яка залежність, яка має react у своїх прямих залежностях, повинна дозволити встановлення react v17.

Також можна вимкнути попередження лише для прямих залежностей певних пакунків. Наприклад, у наведеній нижче конфігурації react v17 буде дозволено лише тоді, коли він є в однорангових залежностях пакунка button v2 або в залежностях будь-якого пакунка card:

{
"pnpm": {
"peerDependencyRules": {
"allowedVersions": {
"button@2>react": "17",
"card>react": "17"
}
}
}
}

pnpm.peerDependencyRules.allowAny

allowAny — масив шаблонів назв пакунків, будь-яка пряма залежність, що відповідає шаблону, буде розвʼязана з будь-якої версії, незалежно від діапазону, вказаного у peerDependencies. Наприклад:

{
"pnpm": {
"peerDependencyRules": {
"allowAny": ["@babel/*", "eslint"]
}
}
}

Наведений вище параметр вимкне попередження про невідповідність версій залежностей, повʼязаних з пакунками @babel/ або eslint.

pnpm.neverBuiltDependencies

Це поле дозволяє ігнорувати збірки певних залежностей. Скрипти "preinstall", "install" і "postinstall" перелічених пакунків не буде виконано під час встановлення.

Приклад поля "pnpm"."neverBuiltDependencies":

{
"pnpm": {
"neverBuiltDependencies": ["fsevents", "level"]
}
}

pnpm.onlyBuiltDependencies

Список назв пакунків, які дозволено виконувати під час встановлення. Якщо це поле наявне, лише для пакунків з цього списку можна буде запустити сценарії встановлення.

Приклад:

{
"pnpm": {
"onlyBuiltDependencies": ["fsevents"]
}
}

pnpm.onlyBuiltDependenciesFile

Цей параметр конфігурації дозволяє користувачам вказати JSON-файл зі списком лише тих пакунків, для яких дозволено запускати сценарії встановлення під час процесу встановлення pnpm. За допомогою цього ви можете підвищити безпеку або гарантувати, що під час встановлення скрипти виконуватимуться лише у певних залежностях.

Приклад:

{
"dependencies": {
"@my-org/policy": "1.0.0"
},
"pnpm": {
"onlyBuiltDependenciesFile": "node_modules/@my-org/policy/onlyBuiltDependencies.json"
}
}

Сам JSON-файл повинен містити масив імен пакунків:

node_modules/@my-org/policy/onlyBuiltDependencies.json
[
"fsevents"
]

pnpm.allowedDeprecatedVersions

Цей параметр дозволяє вимкнути попередження про застарілість певних пакунків.

Приклад:

{
"pnpm": {
"allowedDeprecatedVersions": {
"express": "1",
"request": "*"
}
}
}

У наведеній вище конфігурації pnpm не виводитиме попередження про застарілість для будь-якої версії request і для v1 express.

pnpm.patchedDependencies

Це поле буде додано/оновлено автоматично під час запуску pnpm patch-commit. Це словник, де ключем має бути назва пакунка та його точна версія. Значення має бути відносним шляхом до файлу виправлення.

Приклад:

{
"pnpm": {
"patchedDependencies": {
"express@4.18.1": "patches/express@4.18.1.patch"
}
}
}

pnpm.allowNonAppliedPatches

Якщо true, встановлення не завершиться невдачею, якщо деякі з виправлень з поля patchedDependencies не було застосовано.

{
"pnpm": {
"patchedDependencies": {
"express@4.18.1": "patches/express@4.18.1.patch"
},
"allowNonAppliedPatches": true
}

pnpm.updateConfig

pnpm.updateConfig.ignoreDependencies

Іноді ви не можете оновити залежність. Наприклад, остання версія залежності почала використовувати ESM, але ваш проєкт ще не в ESM. На жаль, такий пакунок завжди буде виведено командою pnpm outdated і оновлено при виконанні pnpm update --latest. Втім, ви можете перелічити пакунки, які не потрібно оновлювати, у полі ignoreDependencies:

{
"pnpm": {
"updateConfig": {
"ignoreDependencies": ["load-json-file"]
}
}
}

Також підтримуються шаблони, тому ви можете ігнорувати будь-які пакунки з області видимості: @babel/*.

pnpm.auditConfig

pnpm.auditConfig.ignoreCves

Список ідентифікаторів CVE, які буде проігноровано командою pnpm audit.

{
"pnpm": {
"auditConfig": {
"ignoreCves": [
"CVE-2022-36313"
]
}
}
}

pnpm.auditConfig.ignoreGhsas

Список кодів GHSA, які буде проігноровано командою pnpm audit.

{
"pnpm": {
"auditConfig": {
"ignoreGhsas": [
"GHSA-42xw-2xvc-qx8m",
"GHSA-4w2v-q235-vp99",
"GHSA-cph5-m8f7-6c5x",
"GHSA-vh95-rmgr-6w4m"
]
}
}
}

pnpm.requiredScripts

Скрипти, перелічені у цьому масиві, будуть потрібні у кожному проєкті робочого простору. Інакше виконання pnpm -r run <script name> завершиться невдачею.

{
"pnpm": {
"requiredScripts": ["build"]
}
}

pnpm.supportedArchitectures

Ви можете вказати архітектури, для яких ви хочете встановити необовʼязкові залежності, навіть якщо вони не відповідають архітектурі системи, на якій виконується встановлення.

Наприклад, у наведеній нижче конфігурації вказано встановити необовʼязкові залежності для Windows x64:

{
"pnpm": {
"supportedArchitectures": {
"os": ["win32"],
"cpu": ["x64"]
}
}
}

Тоді як ця конфігурація встановить необовʼязкові залежності для Windows, macOS та архітектури системи, на якій наразі виконується встановлення. Вона включає артефакти як для x64, так і для arm64 процесорів:

{
"pnpm": {
"supportedArchitectures": {
"os": ["win32", "darwin", "current"],
"cpu": ["x64", "arm64"]
}
}
}

Крім того, supportedArchitectures також підтримує вказівку libc системи.

pnpm.ignoredOptionalDependencies

Якщо необовʼязкова залежність має імʼя у цьому масиві, її буде пропущено. Наприклад:

{
"pnpm": {
"ignoredOptionalDependencies": ["fsevents", "@esbuild/*"]
}
}

pnpm.executionEnv.nodeVersion

Вказує, яку саме версію Node.js слід використовувати для виконання проєкту. pnpm автоматично встановить вказану версію Node.js і використовуватиме її для виконання команд pnpm run або команди pnpm node.

Наприклад:

{
"pnpm": {
"executionEnv": {
"nodeVersion": "16.16.0"
}
}
}

resolutions

Функціонально ідентичне до pnpm.overrides, це поле призначене для полегшення міграції з Yarn.

resolutions та pnpm.overrides буде обʼєднано перед резолюцією пакунків (при цьому pnpm.overrides матиме пріоритет), що може бути корисним, якщо ви мігруєте з Yarn і вам потрібно налаштувати кілька пакунків лише під pnpm.