fs.walk for Node.js (a port of Go's filepath.Walk)
Go to file
AJ ONeal 7001b3e615 add meta files 2020-12-09 04:14:22 -07:00
bin v1.0.0: fs.walk for node 2020-12-09 04:10:56 -07:00
.eslintrc.json initial commit 2020-12-08 17:28:11 -07:00
.gitignore add meta files 2020-12-09 04:14:22 -07:00
.prettierrc.json initial commit 2020-12-08 17:28:11 -07:00
AUTHORS add meta files 2020-12-09 04:14:22 -07:00
LICENSE add meta files 2020-12-09 04:14:22 -07:00
README.md v1.0.0: fs.walk for node 2020-12-09 04:10:56 -07:00
create.js v1.0.0: fs.walk for node 2020-12-09 04:10:56 -07:00
index.js v1.0.0: fs.walk for node 2020-12-09 04:10:56 -07:00
package-lock.json v1.0.0: fs.walk for node 2020-12-09 04:10:56 -07:00
package.json v1.0.0: fs.walk for node 2020-12-09 04:10:56 -07:00
walk.js v1.0.0: fs.walk for node 2020-12-09 04:10:56 -07:00

README.md

Walk.js (@root/walk)

Walk a directory recursively and handle each entity (files, directories, symlnks, etc).

await Walk.walk(pathname, walkFunc);

function walkFunc(err, pathname, dirent) {
  // ...
}

This is a port of Go's filepath.Walk for Node.js v10+ (which introduced fs.readdir withFileTypes) and ES 2021.

Examples

You can use this with Node v12+ using Vanilla JS or ES2021.

ES 2021 Modules

@root/walk can be used with async/await or Promises.

import { walk } from "@root/walk";
import path from "path";

await walk("./", async (err, pathname, dirent) => {
  if (err) {
    // throw an error to stop walking
    // (or return to ignore and keep going)
    console.warn("fs stat error for %s: %s", pathname, err.message);
    return;
  }

  // return false to skip a directory
  // (ex: skipping "dot files")
  if (dirent.isDirectory() && dirent.name.startsWith(".")) {
    return false;
  }

  // fs.Dirent is a slimmed-down, faster version of fs.Stat
  console.log("name:", dirent.name, "in", path.dirname(pathname));
  // (only one of these will be true)
  console.log("is file?", dirent.isFile());
  console.log("is link?", dirent.isSymbolicLink());
});

console.log("Done");

Vanilla JS (ES5)

var Walk = require("@root/walk");
var path = require("path");

Walk.walk("./", function walkFunc(err, pathname, dirent) {
  if (err) {
    throw err;
  }

  if (dirent.isDirectory() && dirent.name.startsWith(".")) {
    return Promise.resolve(false);
  }
  console.log("name:", dirent.name, "in", path.dirname(pathname));

  return Promise.resolve();
}).then(function () {
  console.log("Done");
});

API Documentation

Walk.walk walks pathname (inclusive) and calls walkFunc for each file system entry.

It can be used with Promises:

Walk.walk(pathname, promiseWalker).then(doMore);

Or with async / await:

await Walk.walk(pathname, asyncWalker);

The behavior should exactly match Go's filepath.Walk with 3 exceptions:

  • uses JavaScript Promises/async/await
  • receives dirent rather than lstat (for performance)

walkFunc

Handles each directory entry

function walker(err, pathname, dirent) {
  // `err` is a file system stat error
  // `pathname` is the full pathname, including the file name
  // `dirent` is an fs.Dirent with a `name`, `isDirectory`, `isFile`, etc
  return null;
}