package.json
Файл маніфесту пакунка. Він містить усі метадані пакунка, включно із залежностями, назвою, автором тощо. Це стандарт, який зберігається у всіх основних менеджерах пакунків Node.js, включаючи pnpm.
Окрім традиційного формату package.json
, pnpm також підтримує package.json5
(через json5) та package.yaml
(через js-yaml).
engines
Ви можете вказати версію Node і pnpm, на якій працює ваше програмне забезпечення:
{
"engines": {
"node": ">=10",
"pnpm": ">=3"
}
}
Під час локальної розробки pnpm завжди завершить роботу з повідомленням про помилку, якщо його версія не збігається з версією, вказаною у полі engines
.
Якщо користувач не встановив прапорець конфігурації engineStrict
(див. параметри), це поле є лише рекомендаційним і видаватиме попередження лише тоді, коли ваш пакунок буде встановлено як залежність.
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
}
}
}