:rocket: fast-glob
Is a faster node-glob
alternative.
:bulb: Highlights
- :rocket: Fast by using Streams and Promises. Used readdir-enhanced and micromatch.
- :beginner: User-friendly, since it supports multiple and negated patterns (
['*', '!*.md']
). - :vertical_traffic_light: Rational, because it doesn't read excluded directories (
!**/node_modules
). - :gear: Universal, because it supports Synchronous, Promise and Stream API.
- :money_with_wings: Economy, because it provides
fs.Stats
for matched path if you wanted.
Donate
If you want to thank me, or promote your Issue.
Sorry, but I have work and support for packages requires some time after work. I will be glad of your support and PR's.
Install
$ npm install --save fast-glob
Usage
Asynchronous
const fg = require('fast-glob');
fg(['src/**/*.js', '!src/**/*.spec.js']).then((entries) => console.log(entries));
fg.async(['src/**/*.js', '!src/**/*.spec.js']).then((entries) => console.log(entries));
Synchronous
const fg = require('fast-glob');
const entries = fg.sync(['src/**/*.js', '!src/**/*.spec.js']);
console.log(entries);
Stream
const fg = require('fast-glob');
const stream = fg.stream(['src/**/*.js', '!src/**/*.spec.js']);
const entries = [];
stream.on('data', (entry) => entries.push(entry));
stream.once('error', console.log);
stream.once('end', () => console.log(entries));
API
fg(patterns, [options])
fg.async(patterns, [options])
Returns a Promise<Array>
of matching entries.
patterns
options
See options section for more detailed information.
fg.sync(patterns, [options])
Returns a Array
of matching entries.
fg.stream(patterns, [options])
Returns a ReadableStream
.
Options
cwd
- Type:
string
- Default:
process.cwd()
The current working directory in which to search.
deep
- Type:
number|boolean
- Default:
true
The deep option can be set to true
to traverse the entire directory structure, or it can be set to a number to only traverse that many levels deep.
ignore
- Type:
string[]
- Default:
[]
An array of glob patterns to exclude matches.
dot
- Type:
boolean
- Default:
false
Allow patterns to match filenames starting with a period (files & directories), even if the pattern does not explicitly have a period in that spot.
stats
- Type:
number|boolean
- Default:
false
Return fs.Stats
with path
property instead of file path.
onlyFiles
- Type:
boolean
- Default:
true
Return only files.
onlyDirectories
- Type:
boolean
- Default:
false
Return only directories.
followSymlinkedDirectories
- Type:
boolean
- Default:
true
Follow symlinked directories when expanding **
patterns.
unique
- Type:
boolean
- Default:
true
Prevent duplicate results.
markDirectories
- Type:
boolean
- Default:
false
Add a /
character to directory entries.
absolute
- Type:
boolean
- Default:
false
Return absolute paths for matched entries.
nobrace
- Type:
boolean
- Default:
false
Disable expansion of brace patterns ({a,b}
, {1..3}
).
noglobstar
- Type:
boolean
- Default:
false
Disable matching with globstars (**
).
noext
- Type:
boolean
- Default:
false
Disable extglob support (patterns like +(a|b)
), so that extglobs are regarded as literal characters.
nocase
- Type:
boolean
- Default:
false
Use a case-insensitive regex for matching files.
matchBase
- Type:
boolean
- Default:
false
Allow glob patterns without slashes to match a file path based on its basename. For example, a?b
would match the path /xyz/123/acb
, but not /xyz/acb/123
.
transform
- Type:
Function
- Default:
null
Allows you to transform a path or fs.Stats
object before sending to the array.
const fg = require('fast-glob');
const entries1 = fg.sync(['**/*.scss']);
const entries2 = fg.sync(['**/*.scss'], { transform: (entry) => '_' + entry });
console.log(entries1);
console.log(entries2);
If you are using TypeScript, you probably want to specify your own type of the returned array.
import * as fg from 'fast-glob';
interface IEntry {
path: string;
}
const entries: IEntry[] = fg.sync<IEntry>(['*.md'], {
transform: (entry) => typeof entry === 'string' ? { path: entry } : { path: entry.path }
});
How to exclude directory from reading?
You can use a negative pattern like this: !**/node_modules
. Also you can use ignore
option. Just look at the example below.
If you don't want to read the second
directory, you must write the following pattern: !**/second
.
fg.sync(['**/*.md', '!**/second']);
fg.sync(['**/*.md'], { ignore: '**/second' });
:warning: When you write !**/second/**
it means that the directory will be read, but all the entries will not be included in the results.
You have to understand that if you write the pattern to exclude directories, then the directory will not be read under any circumstances. But… you can specify a more meaningful pattern, which will be launched in parallel with the first.
fg.sync(['**/*.txt', '!**/second', 'first/second/**/*.txt']);
However, be aware that it may not work as you expect in case where inside the second
directory there is a directory matching to the pattern for exluding directory. Yes, sounds complicated. Simpler: the second
directory inside the second
directory.
Compatible with node-glob
?
Not fully, because fast-glob
does not implement all options of node-glob
. See table below.
Benchmarks
Tech specs:
Server: Vultr Bare Metal
- Processor: E3-1270v6 (8 CPU)
- RAM: 32GB
- Disk: SSD
You can see results here for latest release.
Related
Changelog
See the Releases section of our GitHub project for changelogs for each release version.
License
This software is released under the terms of the MIT license.