This codemod transforms usage of the deprecated dirent.path property to use the renamed dirent.parentPath property when working with directory entries.
What It Does
The codemod transforms:
dirent.path → dirent.parentPath
- Works with both
fs.readdir() and fs.opendir() APIs
Usage
npx codemod nodejs/dirent-path-to-parent-path
Examples
Using readdir()
Promises API
Callback API
const { readdir } = require('node:fs/promises');
const entries = await readdir('/some/path', { withFileTypes: true });
for (const dirent of entries) {
console.log(dirent.path);
}
const { readdir } = require('node:fs/promises');
const entries = await readdir('/some/path', { withFileTypes: true });
for (const dirent of entries) {
console.log(dirent.parentPath);
}
const { readdir } = require('node:fs');
readdir('/some/path', { withFileTypes: true }, (err, entries) => {
if (err) throw err;
for (const dirent of entries) {
console.log(dirent.path);
}
});
const { readdir } = require('node:fs');
readdir('/some/path', { withFileTypes: true }, (err, entries) => {
if (err) throw err;
for (const dirent of entries) {
console.log(dirent.parentPath);
}
});
Using opendir()
import { opendir } from 'node:fs/promises';
const dir = await opendir('./');
for await (const dirent of dir) {
console.log(`Found ${dirent.name} in ${dirent.path}`);
}
import { opendir } from 'node:fs/promises';
const dir = await opendir('./');
for await (const dirent of dir) {
console.log(`Found ${dirent.name} in ${dirent.parentPath}`);
}
What is a Dirent?
A Dirent (directory entry) is an object representation of a directory entry, returned by:
fs.readdir() with withFileTypes: true
fs.opendir() and iterating over the directory
Dirent Properties
name - The file name of the directory entry
parentPath - The path to the parent directory (formerly path)
isFile() - Returns true if the entry is a file
isDirectory() - Returns true if the entry is a directory
isSymbolicLink() - Returns true if the entry is a symbolic link
Use withFileTypes: true with readdir() to get Dirent objects instead of strings. This provides file type information without additional stat() calls.
Why the Rename?
The property was renamed from path to parentPath because:
- The value contains the parent directory path, not the entry’s full path
- The old name
path was ambiguous and misleading
parentPath clearly communicates what the property contains
The path property was deprecated in Node.js v20.x. Use parentPath to ensure compatibility with future Node.js versions.
Getting the Full Path
To get the full path of a directory entry, combine parentPath and name:
import { opendir } from 'node:fs/promises';
import { join } from 'node:path';
const dir = await opendir('./');
for await (const dirent of dir) {
const fullPath = join(dirent.parentPath, dirent.name);
console.log(`Full path: ${fullPath}`);
}
Common Use Cases
Filtering Files by Type
import { readdir } from 'node:fs/promises';
import { join } from 'node:path';
const entries = await readdir('./src', { withFileTypes: true });
const files = entries
.filter(dirent => dirent.isFile())
.map(dirent => join(dirent.parentPath, dirent.name));
console.log('Files:', files);
Recursive Directory Traversal
import { readdir } from 'node:fs/promises';
import { join } from 'node:path';
async function* walk(dir) {
const entries = await readdir(dir, { withFileTypes: true });
for (const dirent of entries) {
const fullPath = join(dirent.parentPath, dirent.name);
if (dirent.isDirectory()) {
yield* walk(fullPath);
} else {
yield fullPath;
}
}
}
for await (const filePath of walk('./src')) {
console.log(filePath);
}
Deprecation Reference
This migration addresses DEP0178.