Робочий простір
pnpm має вбудовану підтримку монорепозиторіїв (також відомих як репозиторії з декількома пакунками, репозиторії з декількома проєктами або монолітні репозиторії). Ви можете створити робочий простір, щоб обʼєднати кілька проєктів в одному репозиторії.
Робочий простір повинен мати у своєму корені файл pnpm-workspace.yaml.
Якщо ви розглядаєте управління монорепозиторіями, ви також можете подивитись в бік Bit. Bit використовує pnpm під капотом, але автоматизує багато речей, які зараз виконуються вручну в традиційному робочому просторі, керованому pnpm/npm/Yarn. Про це йдеться у статті про bit install: Безболісне керування залежностями монорепо за допомогою Bit.
Протокол робочого простору (workspace:)
If linkWorkspacePackages is set to true, pnpm will link packages from the workspace if the available packages match the declared ranges. Наприклад, foo@1.0.0 повʼязано з bar, якщо bar має "foo": "^1.0.0" у своїх залежностях і foo@1.0.0 знаходиться у робочому просторі. Однак, якщо bar має "foo": "2.0.0" у залежностях і foo@2.0.0 відсутній у робочому просторі, foo@2.0.0 буде встановлено з реєстру. Така поведінка вносить певну невизначеність.
На щастя, pnpm підтримує протокол workspace:. При використанні цього протоколу pnpm відмовлятиметься виконувати перетворення на будь-що, окрім пакунків локального робочого простору. Отже, якщо ви задасте "foo": "workspace:2.0.0", цього разу встановлення не вдасться, оскільки "foo@2.0.0" у робочому просторі відсутній.
This protocol is especially useful when the linkWorkspacePackages option is set to false. У цьому випадку pnpm буде компонувати пакунки з робочого простору лише за умови використання протоколу workspace:.
Посилання на пакунки робочого простору через псевдоніми
Припустимо, у робочому просторі у вас є пакунок з назвою foo. Зазвичай, ви посилаєтесь на нього як "foo": "workspace:*".
Якщо ви хочете використовувати інший псевдонім, наступний синтаксис також буде працювати: "bar": "workspace:foo@*".
Перед публікацією псевдоніми перетворюються на звичайні залежності від псевдонімів. Вищенаведений приклад стане: "bar": "npm:foo@1.0.0".
Посилання на пакунки робочого простору через їхній відносний шлях
У робочому просторі з 2 пакунками:
+ packages
+ foo
+ bar
bar може мати foo у своїх залежностях, оголошених як "foo": "workspace:../foo". Перед публікацією ці специфікації перетворюються у звичайні специфікації версій, які підтримуються усіма менеджерами пакунків.
Публікація пакунків робочого простору
Коли пакунок робочого простору запаковано до архіву (за допомогою pnpm pack або однієї з команд публікації, наприклад pnpm publish), ми динамічно замінюємо будь-яку залежність workspace: на:
- Відповідну версію у цільовому робочому просторі (якщо ви використовуєте
workspace:*,workspace:~абоworkspace:^) - Асоційований діапазон Semver (для будь-якого іншого типу діапазону)
Наприклад, якщо у робочому просторі є foo, bar, qar, zoo і всі вони мають версію 1.5.0, то наступне:
{
"dependencies": {
"foo": "workspace:*",
"bar": "workspace:~",
"qar": "workspace:^",
"zoo": "workspace:^1.5.0"
}
}
Буде перетворено на:
{
"dependencies": {
"foo": "1.5.0",
"bar": "~1.5.0",
"qar": "^1.5.0",
"zoo": "^1.5.0"
}
}
Ця функція дозволяє вам покладатися на ваші локальні пакунки робочих просторів і водночас публікувати отримані пакунки у віддаленому реєстрі без проміжних кроків публікації — ваші користувачі зможуть використовувати ваші опубліковані робочі простори як будь-які інші пакунки, отримуючи вигоду від гарантій, що їх пропонує Semver.
Процес релізу
Керування версіями пакунків у робочому просторі є складним завданням, і наразі pnpm не надає вбудованого рішення для цього. Однак є 2 добре протестовані інструменти, які працюють з версіями і підтримують pnpm:
Щоб дізнатися, як налаштувати репозиторій за допомогою Rush, прочитайте цю сторінку.
Для використання Changesets із pnpm прочитайте цей посібник.
Усунення несправностей
pnpm не може гарантувати виконання скриптів у топологічному порядку, якщо між залежностями робочого простору є цикли. Якщо pnpm виявить циклічні залежності під час встановлення, він видасть попередження. Якщо pnpm зможе зʼясувати, які залежності спричиняють цикли, він також покаже їх.
Якщо ви бачите повідомлення Існують циклічні залежності робочого простору, перевірте залежності робочого простору, оголошені у dependencies, optionDependencies та devDependencies.
Приклад використання
Ось декілька найпопулярніших відкритих проєктів, які використовують функцію робочого простору pnpm:
Налаштування
linkWorkspacePackages
- Стандартно: false
- Тип: true, false, deep
If this is enabled, locally available packages are linked to node_modules instead of being downloaded from the registry. This is very convenient in a monorepo. Якщо вам потрібно, щоб локальні пакунки також були повʼязані з підзалежностями, ви можете скористатися параметром deep.
Else, packages are downloaded and installed from the registry. However, workspace packages can still be linked by using the workspace: range protocol.
Пакунки звʼязуються, лише якщо їхні версії задовольняють діапазони залежностей.
injectWorkspacePackages
- Стандартно: false
- Тип: Boolean
Вмикає жорстке звʼязування всіх локальних залежностей робочого простору замість їхнього звʼязування у вигляді символічних посилань. Крім того, цього можна досягти за допомогою dependenciesMeta[].injected, що дозволяє вибірково вмикати жорстке зв’язування для певних залежностей.
Навіть якщо цей параметр увімкнено, pnpm надаватиме перевагу дедуплікації введених залежностей за допомогою символічних посилань — якщо тільки не потрібно створювати декілька графів залежностей через невідповідність однорангових залежностей. This behaviour is controlled by the dedupeInjectedDeps setting.
dedupeInjectedDeps
- Стандартно: true
- Тип: Boolean
Якщо цей параметр увімкнено, залежності, які інжектуються, буде звʼязано з робочим простором, коли це можливо. Якщо залежний проєкт та інʼєктована залежність посилаються на ті самі однорангові залежності, то нема потреби фізично копіювати інжектовану залежність у node_modules залежного проєкту; достатньо символічного посилання.
syncInjectedDepsAfterScripts
Додано у: v10.5.0
- Стандартно: undefined
- Тип: String[]
Інʼєкції залежності робочого простору — це колекції жорстких посилань, які не додають і не видаляють файли при зміні їхніх джерел. Це спричиняє проблеми у пакунках, які потрібно зібрати (наприклад, у проєктах на TypeScript).
Цей параметр являє собою список назв скриптів. Коли будь-який з цих скриптів виконується у пакунку робочої області, інʼєкції залежностей всередині node_modules також буде синхронізовано.
preferWorkspacePackages
- Стандартно: false
- Тип: Boolean
If this is enabled, local packages from the workspace are preferred over packages from the registry, even if there is a newer version of the package in the registry.
This setting is only useful if the workspace doesn't use saveWorkspaceProtocol.
sharedWorkspaceLockfile
- Стандартно: true
- Тип: Boolean
If this is enabled, pnpm creates a single pnpm-lock.yaml file in the root of the workspace. This also means that all dependencies of workspace packages will be in a single node_modules (and get symlinked to their package node_modules folder for Node's module resolution).
Advantages of this option:
- кожна залежність є одиночною
- швидші установки в монорепо
- менше змін у перевірках коду, оскільки всі вони містяться в одному файлі
Even though all the dependencies will be hard linked into the root node_modules, packages will have access only to those dependencies that are declared in their package.json, so pnpm's strictness is preserved. This is a result of the aforementioned symbolic linking.
saveWorkspaceProtocol
- Default: rolling
- Тип: true, false, rolling
Цей параметр керує тим, як залежності, приєднані з робочої області, додаються до package.json.
Якщо foo@1.0.0 знаходиться у робочому просторі і ви виконуєте pnpm add foo в іншому проєкті робочого простору, нижче показано, як foo буде додано до поля залежностей. The savePrefix setting also influences how the spec is created.
| saveWorkspaceProtocol | savePrefix | spec |
|---|---|---|
| false | '' | 1.0.0 |
| false | '~' | ~1.0.0 |
| false | '^' | ^1.0.0 |
| true | '' | workspace:1.0.0 |
| true | '~' | workspace:~1.0.0 |
| true | '^' | workspace:^1.0.0 |
| rolling | '' | workspace:* |
| rolling | '~' | workspace:~ |
| rolling | '^' | workspace:^ |
includeWorkspaceRoot
- Стандартно: false
- Тип: Boolean
При рекурсивному виконанні команд у робочій області, виконуйте їх також у кореневому проєкті робочої області.
ignoreWorkspaceCycles
- Стандартно: false
- Тип: Boolean
When set to true, no workspace cycle warnings will be printed.
disallowWorkspaceCycles
- Стандартно: false
- Тип: Boolean
Якщо встановлено значення true, встановлення не вдасться, якщо у робочій області є цикли.
failIfNoMatch
- Стандартно: false
- Тип: Boolean
When set to true, the CLI will exit with a non-zero code if no packages match the provided filters.
For example, the following command will exit with a non-zero code because bad-pkg-name is not present in the workspace:
pnpm --filter=bad-pkg-name test