Spazio di lavoro
pnpm ha il supporto integrato per i monorepository (alias repository multi-pacchetto, repository multi-progetto o repository monolitici). Puoi creare uno spazio di lavoro per unire più progetti all'interno di un unico repository.
A workspace must have a pnpm-workspace.yaml file in its root.
If you are looking into monorepo management, you might also want to look into Bit. Bit utilizza pnpm sotto il cofano ma automatizza molte delle cose che attualmente vengono eseguite manualmente in un'area di lavoro tradizionale gestita da pnpm/npm/Yarn. There's an article about bit install that talks about it: Painless Monorepo Dependency Management with Bit.
Protocollo dello spazio di lavoro (workspace:)
If linkWorkspacePackages is set to true, pnpm will link packages from the workspace if the available packages match the declared ranges. Ad esempio, foo@1.0.0 è collegato a bar se bar ha "foo": "^1.0.0" nelle sue dipendenze e foo@1.0.0 è nell'area di lavoro. Tuttavia, se bar ha "foo": "2.0.0" nelle dipendenze e foo@2.0.0 non è nello spazio di lavoro, foo@2.0.0 verrà installato dal registro. Questo comportamento introduce qualche incertezza.
Fortunatamente, pnpm supporta il protocollo workspace:. Quando viene utilizzato questo protocollo, pnpm si rifiuterà di risolvere qualsiasi altra cosa che non sia un pacchetto locale dello spazio di lavoro. Quindi, se imposti "foo": "workspace:2.0.0", questa volta l'installazione avrà esito negativo perché "foo@2.0.0" non è presente nello spazio di lavoro.
This protocol is especially useful when the linkWorkspacePackages option is set to false. In tal caso, pnpm collegherà i pacchetti dallo spazio di lavoro solo se viene utilizzato il protocollo workspace:.
Riferimenti ai pacchetti dello spazio di lavoro tramite alias
Diciamo che hai un pacchetto nello spazio di lavoro chiamato foo. Di solito, faresti riferimento ad esso tramite "foo": "workspace:*".
Se vuoi usare un alias diverso, funzionerà anche la seguente sintassi: "bar": "workspace:foo@*".
Prima della pubblicazione, gli alias vengono convertiti in normali dipendenze con alias. L'esempio sopra diventerà "bar": "npm:foo@1.0.0".
Riferimenti ai pacchetti dello spazio di lavoro attraverso il percorso relativo
In uno spazio di lavoro con 2 pacchetti:
+ packages
+ foo
+ bar
bar può avere foo nelle sue dipendenze dichiarate come "foo": "workspace:../foo". Prima della pubblicazione, queste specifiche vengono convertite in specifiche della versione normale supportate da tutti i gestori di pacchetti.
Pubblicazione di pacchetti dello spazio di lavoro
Quando un pacchetto dello spazio di lavoro viene compresso in un archivio (che sia tramite pnpm pack o uno dei comandi di pubblicazione come pnpm publish), sostituiamo dinamicamente qualsiasi dipendenza workspace: con:
- La versione corrispondente nello spazio di lavoro di destinazione (se si utilizza
workspace:*,workspace:~oworkspace:^) - L'intervallo semver associato (per qualsiasi altro tipo di intervallo)
Quindi, ad esempio, se abbiamo foo, bar, qar, zoonello spazio di lavoro e sono tutti alla versione 1.5.0, quanto segue:
{
"dependencies": {
"foo": "workspace:*",
"bar": "workspace:~",
"qar": "workspace:^",
"zoo": "workspace:^1.5.0"
}
}
Verrà trasformato in:
{
"dependencies": {
"foo": "1.5.0",
"bar": "~1.5.0",
"qar": "^1.5.0",
"zoo": "^1.5.0"
}
}
Questa funzione ti consente di dipendere dai tuoi pacchetti dello spazio di lavoro locale pur essendo ancora in grado di pubblicare i pacchetti risultanti nel registro remoto senza che necessiti di passaggi di pubblicazione intermedi: i tuoi consumatori saranno in grado di utilizzare i tuoi spazi di lavoro pubblicati come qualsiasi altro pacchetto, ancora beneficiando dalle garanzie semver offerte.
Flusso di lavoro del rilascio
Il controllo delle versioni dei pacchetti all'interno di uno spazio di lavoro è un'attività complessa e attualmente pnpm non fornisce una soluzione integrata per esso. Tuttavia, ci sono 2 strumenti ben testati che gestiscono il controllo delle versioni e supportano pnpm:
For how to set up a repository using Rush, read this page.
For using Changesets with pnpm, read this guide.
Risoluzione dei problemi
pnpm non può garantire che gli script verranno eseguiti in ordine topologico se sono presenti cicli tra le dipendenze dello spazio di lavoro. Se pnpm rileva dipendenze cicliche durante l'installazione, genererà un avviso. Se pnpm è in grado di scoprire quali dipendenze stanno causando i cicli, verrano mostrati anche loro.
Se viene visualizzato il messaggio Sono presenti dipendenze cicliche, ispezionare le dipendenze dello spazio di lavoro dichiarate in dependencies, optionalDependencies e devDependencies.
Esempi di utilizzo
Ecco alcuni dei progetti open source più famosi che utilizzano la funzione dello spazio di lavoro di pnpm:
Configurazione
linkWorkspacePackages
- Predefinito: false
- Tipo: 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. Se hai bisogno che i pacchetti locali siano collegati anche alle dipendenze secondarie, puoi usare l'impostazione deep.
Else, packages are downloaded and installed from the registry. However, workspace packages can still be linked by using the workspace: range protocol.
Packages are only linked if their versions satisfy the dependency ranges.
injectWorkspacePackages
- Predefinito: false
- Tipo: Booleano
Enables hard-linking of all local workspace dependencies instead of symlinking them. Alternatively, this can be achieved using dependenciesMeta[].injected, which allows to selectively enable hard-linking for specific dependencies.
Even if this setting is enabled, pnpm will prefer to deduplicate injected dependencies using symlinks—unless multiple dependency graphs are required due to mismatched peer dependencies. This behaviour is controlled by the dedupeInjectedDeps setting.
dedupeInjectedDeps
- Predefinito: true
- Tipo: Booleano
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
Added in: v10.5.0
- Predefinito: non definito
- Type: String[]
Injected workspace dependencies are collections of hardlinks, which don't add or remove the files when their sources change. This causes problems in packages that need to be built (such as in TypeScript projects).
This setting is a list of script names. When any of these scripts are executed in a workspace package, the injected dependencies inside node_modules will also be synchronized.
preferWorkspacePackages
- Predefinito: false
- Tipo: Booleano
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
- Predefinito: true
- Tipo: Booleano
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:
- ogni dipendenza è un elemento singolo
- installazioni più veloci in un monorepo
- meno modifiche nelle revisioni del codice poiché sono tutte in un unico file
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
- Tipo: true, false, rolling
Questa impostazione controlla il modo in cui le dipendenze collegate dall'area di lavoro vengono aggiunte a package.json.
Se foo@1.0.0 è nell'area di lavoro e si esegue pnpm add foo in un altro progetto dell'area di lavoro, di seguito è riportato come foo verrà aggiunto al campo delle dipendenze. 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
- Predefinito: false
- Tipo: Booleano
Quando si eseguono comandi ricorsivamente in un'area di lavoro, eseguili anche nel progetto dell'area di lavoro radice.
ignoreWorkspaceCycles
- Predefinito: false
- Tipo: Booleano
When set to true, no workspace cycle warnings will be printed.
disallowWorkspaceCycles
- Predefinito: false
- Tipo: Booleano
When set to true, installation will fail if the workspace has cycles.
failIfNoMatch
- Predefinito: false
- Tipo: Booleano
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