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
.
Unless the user has set the engineStrict
config flag (see settings), this
field is advisory only and will only produce warnings when your package is
installed as a dependency.
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
}
}