Menu

Module path de Node.js : path.join ou path.resolve

Le module path construit et décompose les chemins de fichiers correctement pour le système d'exploitation. path.join colle des segments ensemble ; path.resolve les transforme en chemin absolu, en partant du dossier courant.

Cette page contient des éditeurs exécutables. Modifiez, exécutez et voyez la sortie instantanément.

path.join() assemble des segments de chemin avec le bon séparateur et nettoie les .. et les barres obliques en double, mais garde un résultat relatif si vous êtes parti d'un segment relatif. path.resolve() fait le même travail de droite à gauche et renvoie toujours un chemin absolu : il part du répertoire de travail courant, et tout segment absolu rencontré en chemin fait repartir le chemin de zéro. Utilisez join pour construire un chemin, et resolve quand il vous faut un chemin absolu.

Le programme a affiché users/ada/notes.txt, puis users/grace/todo.txt (le .. a retiré ada), puis /srv/app/public/index.html et src/lib/utils.js : les barres obliques en trop et les segments vides ont disparu. join ne traite jamais /public/ comme un nouveau départ ; c'est juste le segment suivant.

path.join ou path.resolve

La différence apparaît quand un segment commence par / ou quand le premier segment est relatif :

Avec /public au milieu, join a produit /srv/app/public/img alors que resolve a jeté tout ce qui précédait et produit /public/img ; les deux ont traité .. de la même façon. Les deux dernières lignes montrent que join a gardé public/index.html relatif, alors que resolve l'a rendu absolu en plaçant le dossier courant devant.

path.joinpath.resolve
RésultatRelatif ou absolu, comme l'entréeToujours absolu
Un segment qui commence par /Un segment comme un autreFait repartir le chemin à cet endroit
Point de départAucunLe répertoire de travail courant
Sans argument'.'Le répertoire de travail courant
Usage courantConstruire un chemin à partir de morceauxTransformer une saisie utilisateur ou une config en chemin absolu

basename, dirname, extname et parse

Ces fonctions décomposent un chemin. Elles ne regardent que la chaîne : le fichier n'a pas besoin d'exister.

Le programme a affiché cat.final.jpg, cat.final, /home/ada/photos et .jpg : extname ne prend que la partie après le dernier point. path.parse renvoie tout d'un coup (root, dir, base, ext, name), et path.format retransforme un tel objet en chaîne.

__dirname et __filename

Dans un fichier CommonJS, __dirname est le chemin absolu du dossier qui contient le fichier, et __filename celui du fichier lui-même. Un chemin relatif comme 'data.json' est relatif à l'endroit où l'utilisateur a lancé node, ce qui casse dès que quelqu'un lance votre script depuis un autre dossier. Construisez plutôt les chemins à partir de __dirname :

Le programme a affiché config.json dark et index.js. Les chemins complets diffèrent sur chaque machine, et c'est justement pour cela qu'on les construit avec path.join(__dirname, ...) au lieu de les taper.

__dirname dans les modules ES : import.meta.dirname

Les modules ES n'ont pas de __dirname ; l'utiliser lève ReferenceError: __dirname is not defined in ES module scope. Depuis Node.js 20.11, import.meta.dirname et import.meta.filename les remplacent :

Le programme a affiché index.js et data/users.json. Avec les versions de Node.js antérieures à 20.11, déduisez le dossier de l'URL du module : path.dirname(fileURLToPath(import.meta.url)), avec fileURLToPath de node:url.

Pourquoi ne pas assembler les chemins avec des chaînes

'data' + '/' + file marche sur macOS et Linux, puis échoue sous Windows, où le séparateur est \, et ne gère ni les .., ni les barres en double, ni une barre manquante. path applique les règles du système sur lequel il tourne. Vous pouvez voir le résultat Windows depuis n'importe quelle machine avec path.win32 :

const path = require('path');

path.posix.join('users', 'ada', 'notes.txt'); // 'users/ada/notes.txt'
path.win32.join('users', 'ada', 'notes.txt'); // 'users\\ada\\notes.txt'
path.sep;                                     // '/' on macOS and Linux, '\\' on Windows

Passez le résultat de path.join à fs.readFile et le même code lit le fichier sur tous les systèmes.

Erreurs fréquentes

S'attendre à ce qu'extname connaisse les doubles extensions. path.extname('archive.tar.gz') vaut '.gz', et un fichier caché comme .env n'a pas d'extension du tout : path.extname('.env') vaut ''. Vérifiez vous-même la fin du nom quand le suffixe complet compte.

Compter sur join pour garder un utilisateur dans un dossier. path.join('/srv/app', '../../etc/passwd') vaut '/etc/passwd'. Avant de lire un fichier nommé par une requête, résolvez le chemin et vérifiez qu'il commence toujours par votre dossier.

Questions fréquentes

Quelle différence entre __dirname et process.cwd() ?

__dirname est le dossier du fichier source courant et ne change jamais. process.cwd() est le dossier depuis lequel l'utilisateur a lancé node. Ils ne sont identiques que si le programme est lancé depuis son propre dossier.

Faut-il utiliser path.join ou path.resolve avec __dirname ?

Les deux marchent pour path.join(__dirname, 'data.json'), puisque __dirname est déjà absolu. Utilisez resolve quand un segment peut lui-même être absolu, comme un chemin saisi par l'utilisateur, et que vous voulez que ce chemin l'emporte.

Comment utiliser le module path avec des URL ?

Ne le faites pas : les URL utilisent toujours / et ont leurs propres règles pour .. et les query strings. Utilisez la classe URL, comme dans new URL('../img/logo.png', 'https://example.com/docs/page').

Illustration des langages de programmation de Coddy

Apprendre à coder avec Coddy

Commencer