What is escalade?
The escalade npm package is a utility designed to simplify the process of ascending file system directories and performing actions based on the presence of specific files or directories. It is particularly useful for tasks such as configuration file discovery, project root identification, and more, by moving up from a given directory until a specified condition is met.
What are escalade's main functionalities?
Finding a specific file in parent directories
This feature allows you to start from a specific directory and move up the directory tree until a file named 'target-file.txt' is found. Once found, you can return a specific path or action based on the discovery.
const escalade = require('escalade');
escalade('/start/path', (dir, names) => {
if (names.includes('target-file.txt')) {
return 'path/to/return';
}
});
Custom condition for directory traversal
This demonstrates how escalade can be used to ascend directories based on a custom condition, such as finding a configuration file with a specific extension. This is useful for dynamically locating project or application configuration files.
const escalade = require('escalade');
escalade('/start/path', (dir, names) => {
if (names.some(name => name.endsWith('.config.js'))) {
return 'path/to/specific/config';
}
});
Other packages similar to escalade
find-up
Similar to escalade, find-up allows you to find a file or directory by looking upwards from a given directory. The main difference is in the API and how you specify the search criteria and handle the results.
pkg-up
pkg-up is focused on finding the closest package.json file in a directory tree. While it serves a more specific purpose compared to escalade, it shares the concept of ascending directories to locate files.
escalade
A tiny (186B to 214B) and fast utility to ascend parent directories
With escalade, you can scale parent directories until you've found what you're looking for.
Given an input file or directory, escalade
will continue executing your callback function until either:
- the callback returns a truthy value
escalade
has reached the root directory (process.cwd()
)
Important:
Please note that escalade
will never traverse beyond the root directory.
Additionally, escalade
only deals with direct ancestry – it will not dive into parents' sibling directories.
Install
$ npm install --save escalade
Modes
There are two "versions" of escalade
available:
"async"
Node.js: >= 8.x
Size (gzip): 214 bytes
Availability: CommonJS, ES Module
This is the primary/default mode. It makes use of async
/await
and util.promisify
.
"sync"
Node.js: >= 6.x
Size (gzip): 186 bytes
Availability: CommonJS, ES Module
This is the opt-in mode, ideal for scenarios where async
usage cannot be supported.
Usage
Example Structure
Assume process.cwd()
is /Users/lukeed/oss/escalade
/Users/lukeed
└── oss
├── license
└── escalade
├── package.json
└── test
└── fixtures
├── index.js
└── foobar
└── demo.js
Example Usage
import { join } from 'path';
import escalade from 'escalade';
const input = join(__dirname, 'demo.js');
const pkg = await escalade(input, (dir, names) => {
console.log('~> dir:', dir);
console.log('~> names:', names);
console.log('---');
if (names.includes('package.json')) {
return 'package.json';
}
});
console.log(pkg);
const license = await escalade(input, (dir, names) => {
console.log('~> dir:', dir);
return names.includes('license') && 'license';
});
console.log(license);
Note: To run the above example with "sync" mode, import from escalade/sync
and remove the await
keyword.
API
escalade(input, callback)
Returns: string|void
or Promise<string|void>
When your callback
locates a file, escalade
will resolve/return with an absolute path.
If your callback
was never satisfied, then escalade
will resolve/return with nothing (undefined).
Important:
The sync
and async
versions share the same API.
The only difference is that sync
is not Promise-based.
input
Type: string
The path from which to start ascending.
This may be a file or a directory path.
However, when input
is a file, escalade
will begin with its parent directory.
Important: Unless given an absolute path, input
will be resolved from process.cwd()
location.
callback
Type: Function
The callback to execute for each ancestry level. It always is given two arguments:
dir
- an absolute path of the current parent directorynames
- a list (string[]
) of contents relative to the dir
parent
Note: The names
list can contain names of files and directories.
When your callback returns a falsey value, then escalade
will continue with dir
's parent directory, re-invoking your callback with new argument values.
When your callback returns a string, then escalade
stops iteration immediately.
If the string is an absolute path, then it's left as is. Otherwise, the string is resolved into an absolute path from the dir
that housed the satisfying condition.
Important: Your callback
can be a Promise/AsyncFunction
when using the "async" version of escalade
.
Benchmarks
Running on Node.js v10.13.0
# Load Time
find-up: 3.948ms
escalade: 0.493ms
escalade/sync: 0.327ms
# Levels: 6 (target = "foo.txt"):
find-up x 30,614 ops/sec ±7.80% (46 runs sampled)
escalade x 46,814 ops/sec ±3.38% (74 runs sampled)
escalade/sync x 9,319 ops/sec ±0.53% (89 runs sampled)
# Levels: 12 (target = "package.json"):
find-up x 26,421 ops/sec ±16.54% (32 runs sampled)
escalade x 49,618 ops/sec ±2.82% (80 runs sampled)
escalade/sync x 4,721 ops/sec ±0.51% (92 runs sampled)
# Levels: 14 (target = "missing123.txt"):
find-up x 30,254 ops/sec ±15.38% (66 runs sampled)
escalade x 50,126 ops/sec ±2.45% (84 runs sampled)
escalade/sync x 4,173 ops/sec ±0.45% (93 runs sampled)
Related
- premove - A tiny (247B) utility to remove items recursively
- totalist - A tiny (195B to 224B) utility to recursively list all (total) files in a directory
- mk-dirs - A tiny (420B) utility to make a directory and its parents, recursively
License
MIT © Luke Edwards