Premiers pas avec les espaces de travail npm
Configuration, commandes et limites des npm workspaces pour gérer un monorepo, lier des paquets voisins et savoir quand ajouter Turborepo ou Nx.
Les espaces de travail npm (npm workspaces), intégrés nativement à npm depuis la version 7, vous permettent de gérer plusieurs packages dans un seul dépôt — un monorepo — depuis une racine unique : un seul npm install hisse les dépendances partagées dans un unique node_modules racine et y crée des liens symboliques vers vos propres packages, de sorte que les imports entre packages se résolvent sans npm link ni republication. Si vous avez une application accompagnée d’une bibliothèque partagée, ou une bibliothèque de composants avec son site de documentation, et que vous en avez assez de npm link, de la duplication de code ou de la gestion de dépôts séparés, il s’agit de la fonctionnalité native qui élimine ces frictions — sans outil tiers. Ce guide couvre la configuration minimale, les options de commandes exactes, les limitations réelles, et les cas où il convient d’ajouter un orchestrateur de build par-dessus.
Points clés
- Les espaces de travail npm sont inclus dans npm 7+ ; la version actuelle est npm 11.18.0, et vous pouvez vérifier votre version avec
npm -v. - La configuration minimale se résume à deux fichiers : un
package.jsonracine avec"private": trueet"workspaces": ["packages/*"], plus unpackage.jsonpar package — un seulnpm installà la racine suffit ensuite à tout connecter. - Pour dépendre d’un package frère, ajoutez-le par son nom avec une plage
"*"; npm crée le lien symbolique à l’installation, de sorte que les modifications apportées au code source sont immédiatement visibles dans chaque consommateur, sans rebuild ni republication. - npm workspaces résout et lie les dépendances, mais n’exécute pas les tâches dans l’ordre des dépendances, ne met pas en cache les sorties de build et ne calcule pas de graphe des packages « affectés ».
- Adoptez Turborepo ou Nx en complément des espaces de travail npm, et non à leur place — npm résout et lie les packages ; ces outils ajoutent l’orchestration des tâches et la mise en cache.
Comment fonctionnent les espaces de travail npm ?
Les espaces de travail npm transforment un dépôt unique en monorepo en hissant les dépendances partagées dans un seul node_modules racine et en créant des liens symboliques vers vos propres packages à côté d’elles. Lorsque vous exécutez npm install à la racine, npm analyse chaque espace de travail, installe une seule fois les dépendances tierces au niveau supérieur, et lie chaque package local dans node_modules via son champ name. Si deux de vos packages dépendent l’un de l’autre, la référence se résout via ce lien symbolique — le CLI npm automatise la liaison dans le cadre de npm install et supprime la nécessité d’exécuter manuellement npm link.
Le même champ workspaces et le même modèle de liens symboliques sont également utilisés par Yarn, pnpm et Bun, de sorte que le modèle mental est transférable d’un gestionnaire de packages à l’autre. La fonctionnalité a été introduite dans npm 7 ; toute version ultérieure fonctionne.
Discover how at OpenReplay.com.
Quelle est la configuration minimale des espaces de travail npm ?
La configuration minimale se résume à deux fichiers : un package.json racine qui déclare l’emplacement des packages, plus un package.json par package. Créez cette structure :
my-monorepo/
├── package.json # racine — privé, liste les espaces de travail
└── packages/
├── utils/
│ └── package.json # @myorg/utils
└── app/
└── package.json # @myorg/app
Le package.json racine nécessite deux champs :
{
"name": "my-monorepo",
"private": true,
"workspaces": ["packages/*"]
}
"private": true vous évite de publier accidentellement la racine, et le glob packages/* indique à npm de traiter chaque répertoire sous packages/ comme un espace de travail. Donnez à chaque package un nom scopé comme @myorg/utils pour éviter les collisions dans le registre :
{
"name": "@myorg/utils",
"version": "1.0.0",
"main": "dist/index.js"
}
Exécutez npm install une seule fois à la racine. Il n’existe qu’un seul fichier de verrouillage à la racine et aucun node_modules à l’intérieur des packages individuels — tout est hissé vers le haut.
Ajouter une dépendance entre packages
Pour dépendre d’un package frère, ajoutez-le par son nom avec une plage "*" ; npm crée le lien symbolique à l’installation, de sorte que les modifications apportées au code source sont immédiatement visibles dans chaque consommateur. Dans @myorg/app :
{
"name": "@myorg/app",
"dependencies": {
"@myorg/utils": "*"
}
}
Exécutez à nouveau npm install à la racine. npm crée un lien symbolique de node_modules/@myorg/utils vers packages/utils, et vous l’importez comme n’importe quel module publié :
import { formatDate } from "@myorg/utils";
Comme il s’agit d’un lien symbolique, toute modification du code source dans packages/utils se répercute immédiatement dans app sans rebuild ni republication — c’est l’avantage décisif par rapport à npm link. Un point de vigilance inter-outils : npm ne prend pas en charge le protocole de version workspace: utilisé par pnpm et Yarn Berry. Passer un spécificateur workspace: provoque un échec npm avec EUNSUPPORTEDPROTOCOL ; avec npm, vous référencez les packages internes par leur nom et une plage ("*"), et non workspace:*.
Les commandes du quotidien
Les options prêtent souvent à confusion, car le singulier et le pluriel ont des significations différentes. Ajoutez une dépendance à un seul package avec -w, à tous les packages avec --workspaces ; exécutez un script dans un seul espace de travail avec -w, et dans tous avec --workspaces --if-present, qui ignore les packages ne définissant pas ce script.
# Installer une dépendance dans UN seul espace de travail
npm install lodash -w @myorg/app
# Installer une dépendance de développement dans un espace de travail
npm install -D vitest -w @myorg/utils
# Installer une dépendance dans TOUS les espaces de travail
npm install eslint --workspaces
# Exécuter un script dans UN seul espace de travail
npm run build -w @myorg/utils
# Exécuter un script dans TOUS les espaces de travail, en ignorant ceux qui ne le définissent pas
npm run test --workspaces --if-present
-w est l’abréviation de --workspace, et --workspaces (ou -ws) cible tous les espaces de travail. Configurez les scripts racine une seule fois pour que npm run build se propage à tous :
{
"scripts": {
"build": "npm run build --workspaces --if-present",
"test": "npm run test --workspaces --if-present"
}
}
Pour vérifier que le graphe est correctement lié, exécutez npm ls -ws ou interrogez-le avec npm query .workspace.
Les limites : ce que les espaces de travail npm ne font pas
Les espaces de travail npm résolvent et lient les dépendances, mais n’exécutent pas les tâches dans l’ordre des dépendances, ne mettent pas en cache les sorties de build et ne calculent pas de graphe des packages « affectés ». Si votre application importe une bibliothèque, vous devez d’abord builder cette bibliothèque — l’exécution d’un script sur plusieurs espaces de travail échouera lorsqu’ils dépendent les uns des autres, car npm n’exécute pas dans l’ordre topologique, une amélioration dont la demande reste ouverte. Ordonnez les tâches explicitement, ou utilisez npm-run-all :
{
"scripts": {
"build:utils": "npm run build -w @myorg/utils",
"build:app": "npm run build -w @myorg/app",
"build": "npm run build:utils && npm run build:app"
}
}
Deux autres points d’attention :
-
node_modulesimbriqués. Lorsque deux packages nécessitent des versions incompatibles d’une même dépendance, npm cesse de hisser et installe une copie imbriquée à l’intérieur de l’un des packages. Épinglez une version partagée unique avec le champoverridesà la racine pour maintenir l’arborescence à plat :{ "overrides": { "lodash": "^4.17.21" } } -
Les valeurs par défaut des scripts d’installation se durcissent. npm v12, dont la sortie est prévue en juillet 2026, change
allowScriptspour qu’il soit désactivé par défaut, de sorte quenpm installn’exécutera plus les scriptspreinstall,installoupostinstalldes dépendances à moins qu’ils ne soient explicitement autorisés. Si vos espaces de travail s’appuient sur une étape de buildpostinstallouprepare, prévoyez de l’approuver explicitement — ces changements apparaissent sous forme d’avertissements dans npm 11.16.0 ou version ultérieure pour vous permettre de vous y préparer à l’avance.
À noter que « l’absence d’intégration native avec React/Vue/Vite » relève d’un choix de périmètre, et non d’un défaut : les espaces de travail sont agnostiques vis-à-vis des frameworks par conception. La génération d’applications n’est pas leur rôle.
Quand adopter Turborepo ou Nx
Adoptez Turborepo ou Nx en complément des espaces de travail npm, et non à leur place : npm résout et lie vos packages, tandis que ces outils ajoutent l’orchestration des tâches, la mise en cache et les builds basés sur le graphe des packages affectés pour les dépôts de grande taille. Ce sont des couches complémentaires.
| Problématique | npm workspaces | Turborepo / Nx |
|---|---|---|
| Installation et liaison des packages | ✅ | Délègue à npm |
| Ordre des dépendances de tâches | ❌ scripts manuels | ✅ topologique |
| Mise en cache des builds/tests | ❌ | ✅ locale + distante |
| Builds « affectés » | ❌ | ✅ graphe basé sur les changements |
Faites appel à l’un de ces outils lorsque les scripts ordonnés deviennent ingérables, que la CI rebuilde tout à chaque changement, ou que vous souhaitez n’exécuter les tâches que pour les packages touchés par un commit. Notez que le Lerna moderne est désormais adossé à Nx — l’ancienne recommandation « npm + Lerna » s’est fondue dans ce même modèle de couches.
Les espaces de travail npm couvrent environ les 80 premiers pourcents des besoins d’un petit monorepo sans aucun outillage supplémentaire. Mettez en place la configuration en deux fichiers, configurez vos options, ordonnez vos builds, et n’ajoutez un orchestrateur que lorsque le pipeline — et non la résolution des dépendances — devient le goulot d’étranglement. Exécutez sur une version Active LTS de Node (Node 20 a atteint sa fin de vie le 30 avril 2026) et vérifiez que npm -v indique 7 ou une version ultérieure avant de commencer.
FAQ
Les espaces de travail npm nécessitent-ils encore un fichier de verrouillage par package, ou un seul à la racine ?
Les espaces de travail npm produisent un seul package-lock.json à la racine du dépôt, et non un par package. Un npm install à la racine résout les dépendances de tous les espaces de travail ensemble et les enregistre dans ce fichier de verrouillage unique, tandis que les packages individuels ne possèdent pas leur propre répertoire node_modules, car les dépendances sont hissées à la racine. Ce modèle à fichier de verrouillage unique est ce qui garantit la cohérence des versions entre tous les packages, et c'est pourquoi vous exécutez toujours l'installation depuis la racine.
Pourquoi 'npm run build --workspaces' échoue-t-il lorsque mes packages dépendent les uns des autres ?
Il échoue parce que npm n'exécute pas les scripts d'espaces de travail dans l'ordre topologique (ordre des dépendances) ; il les exécute dans l'ordre où les espaces de travail sont listés, de sorte qu'un consommateur peut être buildé avant que la bibliothèque qu'il importe n'existe, produisant des erreurs 'cannot find module' ou des échecs de résolution. Cela reste une amélioration npm en attente (issue 4139). Corrigez cela en définissant des scripts ordonnés explicites qui buildent d'abord la bibliothèque, ou en utilisant un outil comme npm-run-all, Turborepo ou Nx.
Puis-je utiliser le protocole 'workspace:*' avec npm comme je le fais avec pnpm ou Yarn ?
Non. npm ne prend pas en charge le protocole de version workspace: utilisé par pnpm et Yarn Berry, et passer un spécificateur workspace: provoque un échec npm avec EUNSUPPORTEDPROTOCOL (documenté dans npm/cli issue 8845). Avec npm, référencez les packages internes par leur nom et une plage normale telle que '@myorg/utils': '*' ; npm les lie symboliquement à l'installation. Si vous migrez un dépôt pnpm ou Yarn vers npm, réécrivez chaque spécificateur workspace: en une plage ordinaire.
Ai-je encore besoin de 'npm link' avec les espaces de travail ?
Non. Les espaces de travail npm automatisent la liaison dans le cadre de npm install, en créant un lien symbolique de chaque package local dans le node_modules racine via son champ name, ce qui supprime la nécessité d'exécuter manuellement npm link. Dès qu'un package liste un package frère comme dépendance avec une plage '*', un seul npm install à la racine établit le lien symbolique, et les modifications apportées au package source sont immédiatement visibles dans chaque consommateur, sans rebuild ni republication.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k