Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Paths: node:path and import.meta.dirname

A path is the address of a file on disk, for example data/posts.json or C:\blog\data\posts.json. Windows separates the parts with a backslash, Linux and macOS with a forward slash. The built-in node:path module builds and parses paths so that the code works the same on any system.

Building a path

path.join() glues path parts together with the right separator:

import path from 'node:path';
 
const file = path.join('data', 'posts', 'first.json');
 
console.log(file);

On Linux and macOS it prints data/posts/first.json, on Windows data\posts\first.json. The function also removes extra separators and resolves ...

Parsing a path

import path from 'node:path';
 
const file = '/home/anna/blog/data/posts.json';
 
console.log(path.basename(file));         // posts.json
console.log(path.extname(file));          // .json
console.log(path.basename(file, '.json')); // posts
console.log(path.dirname(file));          // /home/anna/blog/data
FunctionReturns
path.basename(p)The file name
path.extname(p)The extension with the dot
path.dirname(p)The folder the file is in
path.join(...)The joined path
path.resolve(...)An absolute path — from the disk root

What a path is relative to

A relative path like data/posts.json is resolved from the terminal's current folder — process.cwd() — not from the folder of the file with the code. Start the program from another folder and the file is not found.

The current module's folder

To make a path independent of where the program was started, build it from the module's own folder. In ES modules it is stored in import.meta.dirname, and the full path to the file in import.meta.filename:

import path from 'node:path';
 
const dataFile = path.join(import.meta.dirname, 'data', 'posts.json');
 
console.log(path.isAbsolute(dataFile)); // true
console.log(path.basename(import.meta.filename));

The first line prints true: the path starts at the disk root. The second prints the name of the file that contains the code.

In the blog project

The module that works with posts lives in src/posts.js, and the data in data/posts.json in the root. The path to the data is built like this:

// src/posts.js
import path from 'node:path';
 
const DATA_FILE = path.join(import.meta.dirname, '..', 'data', 'posts.json');
 
export { DATA_FILE };

.. goes one folder up — from src to the project root. Now node src/server.js and npm start find the same file from any folder.

Common mistake

Older articles build paths with __dirname. That variable exists only in CommonJS; in an ES module the code fails:

// src/posts.js
const file = __dirname + '/data/posts.json';
// ReferenceError: __dirname is not defined in ES module scope

Use import.meta.dirname — it appeared in Node.js 20.11 and works in every version the course targets. And build paths with path.join(), not string concatenation.

Thanks for reading!

Donate to the site — we work hard for you.