Comment Node résout vos imports
Remontée node_modules, exports, arbre transitif.
Objectifs
À la fin de cette leçon, vous saurez :
- suivre la recherche de
import x from "pg"jusqu'au fichier réel ; - comprendre les dépendances transitives et l'arbre node_modules ;
- lire un package.json tiers (main/exports).
🔗 Pour vous rafraîchir la mémoire : package.json et scripts npm · modules : import/export
Deux imports, deux mondes
import { Pool } from "pg"; // sans ./ → package de node_modules
import { util } from "./util.js"; // avec ./ → fichier du projet
La présence du préfixe relatif change tout : Node cherche soit sur le disque à côté du fichier courant, soit dans l'arbre des dépendances installées.
La remontée de node_modules
Pour "pg", Node cherche, depuis le dossier du fichier qui importe :
/home/projet/src/node_modules/pg
/home/projet/node_modules/pg ← trouvé ici
/home/node_modules/pg
/node_modules/pg
Il remonte dossier par dossier jusqu'à trouver. Conséquence pratique : votre code fonctionne quel que soit sa profondeur dans le projet, tant qu'un node_modules ancêtre contient la dépendance.
Ce que contient le package trouvé
Dans node_modules/pg/package.json, deux champs guident Node :
{
"name": "pg",
"main": "./lib/index.js", // point d'entrée classique
"exports": { ".": "./lib/index.js", "types": ... } // contrôle moderne
}
exports (moderne) liste précisément ce que le package autorise d'importer : tout le reste est inaccessible — c'est une interface publique déclarée. Vous ne pouvez pas importer un fichier interne par accident.
L'arbre des transitives
Votre pg a lui-même des dépendances (pg-connection-string, pg-protocol...). npm les installe aussi :
npm ls # votre arbre complet
npm ls --depth=0 # seulement vos dépendances directes
todo-api@1.0.0
└─┬ pg@8.11.3
├── pg-connection-string@2.6.2
├── pg-pool@3.6.2
└── ...
Ces dépendances transitives expliquent pourquoi installer un petit package peut ajouter des centaines de fichiers — et pourquoi npm audit scanne tout l'arbre, pas juste vos choix directs. Une vulnérabilité en profondeur vous concerne autant.
Exercice
- Ouvrez
node_modules/pg/package.json: retrouvez main/exports. - Listez votre arbre avec
npm ls. Comptez vos directes vs totales. - Importez délibérément un chemin interne interdit (
pg/lib/chose-inexistante) : quelle erreur ?
Résumé
- Sans
./= recherche ascendante dans les node_modules. - exports = interface publique déclarée d'un package.
- Transitives = l'arbre caché derrière chaque install ; auditées comme les vôtres.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
Question 3. Une erreur du type ERR_PACKAGE_PATH_NOT_EXPORTED : le package refuse explicitement cet accès. C'est le contrat exports appliqué — protection contre la dépendance aux détails internes qui pourraient changer sans préavis.