Description
Since dirent.path is deprecated (DEP0178) and has reached End-of-Life status, we should provide a codemod to replace it.
- The codemod should replace all instances of
dirent.path with dirent.parentPath.
- The codemod should handle different usage patterns including property access, destructuring, and method chaining.
- The codemod should work with various fs operations that return
fs.Dirent objects.
- The codemod should preserve existing functionality while updating to the supported API.
Additional Information
Note that dirent.path was removed in Node.js v24.0.0 due to its lack of consistency across release lines. Users should use dirent.parentPath instead. The path property was deprecated because it provided inconsistent behavior and could be confusing when working with directory entries.
The dirent.parentPath property provides the same functionality but with clearer semantics - it represents the path to the parent directory of the file that the fs.Dirent object refers to.
Examples
Case 1: Basic property access
Before:
const { readdir } = require('node:fs/promises');
const entries = await readdir('/some/path', { withFileTypes: true });
for (const dirent of entries) {
console.log(dirent.path);
}
After:
const { readdir } = require('node:fs/promises');
const entries = await readdir('/some/path', { withFileTypes: true });
for (const dirent of entries) {
console.log(dirent.parentPath);
}
Case 2: ESM import with property access
Before:
import { readdir } from 'node:fs/promises';
const entries = await readdir('./directory', { withFileTypes: true });
entries.forEach(dirent => {
const fullPath = `${dirent.path}/${dirent.name}`;
console.log(fullPath);
});
After:
import { readdir } from 'node:fs/promises';
const entries = await readdir('./directory', { withFileTypes: true });
entries.forEach(dirent => {
const fullPath = `${dirent.parentPath}/${dirent.name}`;
console.log(fullPath);
});
Case 3: Destructuring assignment
Before:
const fs = require('node:fs');
fs.readdir('/path', { withFileTypes: true }, (err, dirents) => {
if (err) throw err;
dirents.forEach(({ name, path, isDirectory }) => {
console.log(`${name} in ${path}`);
});
});
After:
const fs = require('node:fs');
fs.readdir('/path', { withFileTypes: true }, (err, dirents) => {
if (err) throw err;
dirents.forEach(({ name, parentPath, isDirectory }) => {
console.log(`${name} in ${parentPath}`);
});
});
Case 4: Using with fs.opendir
Before:
import { opendir } from 'node:fs/promises';
const dir = await opendir('./');
for await (const dirent of dir) {
console.log(`Found ${dirent.name} in ${dirent.path}`);
}
After:
import { opendir } from 'node:fs/promises';
const dir = await opendir('./');
for await (const dirent of dir) {
console.log(`Found ${dirent.name} in ${dirent.parentPath}`);
}
Case 5: Conditional access
Before:
const { readdirSync } = require('node:fs');
const entries = readdirSync('./', { withFileTypes: true });
const files = entries.filter(dirent => {
return dirent.isFile() && dirent.path.includes('src');
});
After:
const { readdirSync } = require('node:fs');
const entries = readdirSync('./', { withFileTypes: true });
const files = entries.filter(dirent => {
return dirent.isFile() && dirent.parentPath.includes('src');
});
Case 6: Building full file paths
Before:
import { join } from 'node:path';
import { readdir } from 'node:fs/promises';
async function getFilePaths(directory) {
const dirents = await readdir(directory, { withFileTypes: true });
return dirents
.filter(dirent => dirent.isFile())
.map(dirent => join(dirent.path, dirent.name));
}
After:
import { join } from 'node:path';
import { readdir } from 'node:fs/promises';
async function getFilePaths(directory) {
const dirents = await readdir(directory, { withFileTypes: true });
return dirents
.filter(dirent => dirent.isFile())
.map(dirent => join(dirent.parentPath, dirent.name));
}
Case 7: Complex object manipulation
Before:
const fs = require('node:fs');
function processDirectory(path) {
const entries = fs.readdirSync(path, { withFileTypes: true });
return entries.map(dirent => ({
name: dirent.name,
directory: dirent.path,
type: dirent.isDirectory() ? 'dir' : 'file',
fullPath: `${dirent.path}/${dirent.name}`
}));
}
After:
const fs = require('node:fs');
function processDirectory(path) {
const entries = fs.readdirSync(path, { withFileTypes: true });
return entries.map(dirent => ({
name: dirent.name,
directory: dirent.parentPath,
type: dirent.isDirectory() ? 'dir' : 'file',
fullPath: `${dirent.parentPath}/${dirent.name}`
}));
}
Case 8: Recursive directory traversal
Before:
import { readdir } from 'node:fs/promises';
import { join } from 'node:path';
async function walkDirectory(dirPath) {
const dirents = await readdir(dirPath, { withFileTypes: true });
for (const dirent of dirents) {
const currentPath = join(dirent.path, dirent.name);
if (dirent.isDirectory()) {
await walkDirectory(currentPath);
} else {
console.log(`File: ${currentPath}`);
}
}
}
After:
import { readdir } from 'node:fs/promises';
import { join } from 'node:path';
async function walkDirectory(dirPath) {
const dirents = await readdir(dirPath, { withFileTypes: true });
for (const dirent of dirents) {
const currentPath = join(dirent.parentPath, dirent.name);
if (dirent.isDirectory()) {
await walkDirectory(currentPath);
} else {
console.log(`File: ${currentPath}`);
}
}
}
Refs
Description
Since
dirent.pathis deprecated (DEP0178) and has reached End-of-Life status, we should provide a codemod to replace it.dirent.pathwithdirent.parentPath.fs.Direntobjects.Additional Information
Note that
dirent.pathwas removed in Node.js v24.0.0 due to its lack of consistency across release lines. Users should usedirent.parentPathinstead. Thepathproperty was deprecated because it provided inconsistent behavior and could be confusing when working with directory entries.The
dirent.parentPathproperty provides the same functionality but with clearer semantics - it represents the path to the parent directory of the file that thefs.Direntobject refers to.Examples
Case 1: Basic property access
Before:
After:
Case 2: ESM import with property access
Before:
After:
Case 3: Destructuring assignment
Before:
After:
Case 4: Using with fs.opendir
Before:
After:
Case 5: Conditional access
Before:
After:
Case 6: Building full file paths
Before:
After:
Case 7: Complex object manipulation
Before:
After:
Case 8: Recursive directory traversal
Before:
After:
Refs
dirent.pathdirent.pathnode#55548