Si aucun répertoire node_modules n'est trouvé dans le répertoire de travail ou plus haut, Bun abandonnera la résolution de modules de style Node.js en faveur de l'algorithme de résolution de modules Bun.
Avec la résolution de modules de style Bun, tous les packages importés sont auto-installés à la volée dans un cache de modules global pendant l'exécution (le même cache utilisé par bun install).
import { foo } from "foo"; // installe la version `latest`
foo();La première fois que vous exécutez ce script, Bun auto-installera "foo" et le mettra en cache. La prochaine fois que vous exécuterez le script, il utilisera la version mise en cache.
Résolution de version
Pour déterminer quelle version installer, Bun suit l'algorithme suivant :
- Vérifie la présence d'un fichier
bun.lockà la racine du projet. S'il existe, utilise la version spécifiée dans le lockfile. - Sinon, parcourt l'arborescence pour trouver un
package.jsonqui inclut"foo"comme dépendance. S'il est trouvé, utilise la version semver spécifiée ou la plage de versions. - Sinon, utilise
latest.
Comportement du cache
Une fois qu'une version ou une plage de versions a été déterminée, Bun va :
- Vérifier le cache de modules pour une version compatible. S'il en existe une, l'utiliser.
- Lors de la résolution de
latest, Bun vérifiera sipackage@latesta été téléchargé et mis en cache dans les dernières 24 heures. Si oui, l'utiliser. - Sinon, télécharger et installer la version appropriée depuis le registre
npm.
Installation
Les packages sont installés et mis en cache dans <cache>/<pkg>@<version>, donc plusieurs versions du même package peuvent être mises en cache en même temps. De plus, un lien symbolique est créé sous <cache>/<pkg>/<version> pour rendre plus rapide la recherche de toutes les versions d'un package qui existent dans le cache.
Spécificateurs de version
Tout cet algorithme de résolution peut être court-circuité en spécifiant une version ou une plage de versions directement dans votre instruction d'importation.
import { z } from "zod@3.0.0"; // version spécifique
import { z } from "zod@next"; // tag npm
import { z } from "zod@^3.20.0"; // plage semverAvantages
Cette approche d'auto-installation est utile pour plusieurs raisons :
- Efficacité spatiale — Chaque version d'une dépendance n'existe qu'à un seul endroit sur le disque. C'est un gain énorme d'espace et de temps par rapport aux installations redondantes par projet.
- Portabilité — Pour partager des scripts et des gists simples, votre fichier source est autonome. Pas besoin de
zipperun répertoire contenant votre code et vos fichiers de configuration. Avec les spécificateurs de version dans les instructionsimport, même unpackage.jsonn'est pas nécessaire. - Commodité — Il n'est pas nécessaire d'exécuter
npm installoubun installavant d'exécuter un fichier ou un script. Il suffit de fairebun run. - Compatibilité ascendante — Parce que Bun respecte toujours les versions spécifiées dans
package.jsons'il en existe un, vous pouvez passer à la résolution de style Bun avec une seule commande :rm -rf node_modules.
Limitations
- Pas d'Intellisense. L'auto-complétion TypeScript dans les IDE repose sur l'existence de fichiers de déclaration de type à l'intérieur de
node_modules. Nous étudions diverses solutions à ce problème. - Pas de support patch-package
FAQ
En quoi cela diffère-t-il de ce que fait pnpm ?
Avec pnpm, vous devez exécuter pnpm install, ce qui crée un dossier node_modules de liens symboliques pour que le runtime résolve. En revanche, Bun résout les dépendances à la volée lorsque vous exécutez un fichier ; il n'est pas nécessaire d'exécuter une commande install au préalable. Bun ne crée pas non plus de dossier node_modules.
En quoi cela diffère-t-il de Yarn Plug'N'Play ?
Avec Yarn, vous devez exécuter yarn install avant d'exécuter un script. En revanche, Bun résout les dépendances à la volée lorsque vous exécutez un fichier ; il n'est pas nécessaire d'exécuter une commande install au préalable.
Yarn Plug'N'Play utilise également des fichiers zip pour stocker les dépendances. Cela rend le chargement des dépendances plus lent à l'exécution, car les lectures à accès aléatoire sur les fichiers zip ont tendance à être plus lentes que la recherche équivalente sur disque.
En quoi cela diffère-t-il de ce que fait Deno ?
Deno nécessite un spécificateur npm: avant chaque import npm, ne prend pas en charge les cartes d'importation via compilerOptions.paths dans tsconfig.json, et a un support incomplet pour les paramètres package.json. Contrairement à Deno, Bun ne prend pas actuellement en charge les importations d'URL.