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

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
}
}