Робочий простір
pnpm має вбудовану підтримку монорепозиторіїв (також відомих як репозиторії з декількома пакунками, репозиторії з декількома проєктами або монолітні репозиторії). Ви можете створити робочий простір, щоб обʼєднати кілька проєктів в одному репозиторії.
Робочий простір повинен мати файл pnpm-workspace.yaml у корені.
Якщо ви розглядаєте управління монорепозиторіями, ви також можете розглянути Bit.
Bit використовує pnpm під капотом, але автоматизує багато речей, які зараз виконуються вручну в традиційному робочому просторі, керованому pnpm/npm/Yarn. Є стаття про bit install, яка розповідає про це: Безболісне керування залежностями Monorepo за допомогою Bit.
Протокол робочого простору (workspace:)
Якщо linkWorkspacePackages встановлено у true, pnpm буде лінкувати пакунки з робочого простору, якщо доступні пакунки відповідають оголошеним діапазонам. For instance, foo@1.0.0 is linked into bar if
bar has "foo": "^1.0.0" in its dependencies and foo@1.0.0 is in the workspace. However, if bar has
"foo": "2.0.0" in dependencies and foo@2.0.0 is not in the workspace,
foo@2.0.0 will be installed from the registry. Така поведінка вносить певну невизначеність.
Luckily, pnpm supports the workspace: protocol. При використанні цього протоколу pnpm відмовлятиметься виконувати перетворення на будь-що, окрім пакунків локального робочого простору. So, if you set "foo": "workspace:2.0.0", this time
installation will fail because "foo@2.0.0" isn't present in the workspace.
Цей протокол особливо корисний, коли параметр linkWorkspacePackages має значення false. In that case, pnpm will only link packages from the workspace if
the workspace: protocol is used.
Посилання на пакунки робочого простору через псевдоніми
Let's say you have a package in the workspace named foo. Usually, you would
reference it as "foo": "workspace:*".
If you want to use a different alias, the following syntax will work too:
"bar": "workspace:foo@*".
Перед публікацією псевдоніми перетворюються на звичайні залежності від псевдонімів. The above
example will become: "bar": "npm:foo@1.0.0".
Посилання на пакунки робочого простору через їхній відносний шлях
У робочому просторі з 2 пакунками:
+ packages
+ foo
+ bar
bar may have foo in its dependencies declared as
"foo": "workspace:../foo". Перед публікацією ці специфікації перетворюються у звичайні специфікації версій, які підтримуються усіма менеджерами пакунків.
Публікація пакунків робочого простору
When a workspace package is packed into an archive (whether it's through
pnpm pack or one of the publish commands like pnpm publish), we dynamically
replace any workspace: dependency by:
- Відповідну версію у цільовому робочому просторі (якщо ви використовуєте
workspace:,workspace:*,workspace:~абоworkspace:^) - Асоційований діапазон Semver (для будь-якого іншого типу діапазону)
Порожній workspace: без діапазону версій розглядається як workspace:*.
So for example, if we have foo, bar, qar, zoo in the workspace and they all are at version 1.5.0, the following:
{
"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:
For how to set up a repository using Rush, read this page.
For using Changesets with pnpm, read this guide.
Усунення несправностей
pnpm не може гарантувати виконання скриптів у топологічному порядку, якщо між залежностями робочого простору є цикли. Якщо pnpm виявить циклічні залежності під час встановлення, він видасть попередження. Якщо pnpm зможе зʼясувати, які залежності спричиняють цикли, він також покаже їх.
If you see the message There are cyclic workspace dependencies, please inspect workspace dependencies declared in dependencies, optionalDependencies and devDependencies.
Приклад використання
Ось декілька найпопулярніших відкритих проєктів, які використовують функцію робочого простору pnpm:
Налаштування
linkWorkspacePackages
- Стандартно: false
- Type: 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. If you need local packages to also be linked to subdependencies, you
can use the deep setting.
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 надаватиме перевагу дедуплікації введених залежностей за допомогою символічних посилань — якщо тільки не потрібно створювати декілька графів залежностей через невідповідність однорангових залежностей. Ця поведінка контролюється параметром dedupeInjectedDeps.
dedupeInjectedDeps
- Default: true
- Тип: Boolean
When this setting is enabled, dependencies that are injected will be symlinked from the workspace whenever possible. If the dependent project and the injected dependency reference the same peer dependencies, then it is not necessary to physically copy the injected dependency into the dependent's node_modules; a symlink is sufficient.
syncInjectedDepsAfterScripts
Додано у: v10.5.0
- Default: 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.
Цей параметр корисний лише у тому випадку, якщо у робочому просторі не використовується saveWorkspaceProtocol .
sharedWorkspaceLockfile
- Default: 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
- Type: true, false, rolling
This setting controls how dependencies that are linked from the workspace are added to package.json.
If foo@1.0.0 is in the workspace and you run pnpm add foo in another project of the workspace, below is how foo will be added to the dependencies field. Параметр savePrefix також впливає на те, як створюється специфікація.
| 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
When set to true, installation will fail if the workspace has cycles.
failIfNoMatch
- Стандартно: false
- Тип: Boolean
Якщо встановлено значення true, CLI завершить роботу з ненульовим кодом, якщо жоден пакунок не відповідає наданим фільтрам.
Наприклад, наступна команда завершиться з ненульовим кодом, оскільки bad-pkg-name відсутній у робочій області:
pnpm --filter=bad-pkg-name test