1 | # fast-glob
|
---|
2 |
|
---|
3 | > It's a very fast and efficient [glob][glob_definition] library for [Node.js][node_js].
|
---|
4 |
|
---|
5 | This package provides methods for traversing the file system and returning pathnames that matched a defined set of a specified pattern according to the rules used by the Unix Bash shell with some simplifications, meanwhile results are returned in **arbitrary order**. Quick, simple, effective.
|
---|
6 |
|
---|
7 | ## Table of Contents
|
---|
8 |
|
---|
9 | <details>
|
---|
10 | <summary><strong>Details</strong></summary>
|
---|
11 |
|
---|
12 | * [Highlights](#highlights)
|
---|
13 | * [Donation](#donation)
|
---|
14 | * [Old and modern mode](#old-and-modern-mode)
|
---|
15 | * [Pattern syntax](#pattern-syntax)
|
---|
16 | * [Basic syntax](#basic-syntax)
|
---|
17 | * [Advanced syntax](#advanced-syntax)
|
---|
18 | * [Installation](#installation)
|
---|
19 | * [API](#api)
|
---|
20 | * [Asynchronous](#asynchronous)
|
---|
21 | * [Synchronous](#synchronous)
|
---|
22 | * [Stream](#stream)
|
---|
23 | * [patterns](#patterns)
|
---|
24 | * [[options]](#options)
|
---|
25 | * [Helpers](#helpers)
|
---|
26 | * [generateTasks](#generatetaskspatterns-options)
|
---|
27 | * [isDynamicPattern](#isdynamicpatternpattern-options)
|
---|
28 | * [escapePath](#escapepathpattern)
|
---|
29 | * [Options](#options-3)
|
---|
30 | * [Common](#common)
|
---|
31 | * [concurrency](#concurrency)
|
---|
32 | * [cwd](#cwd)
|
---|
33 | * [deep](#deep)
|
---|
34 | * [followSymbolicLinks](#followsymboliclinks)
|
---|
35 | * [fs](#fs)
|
---|
36 | * [ignore](#ignore)
|
---|
37 | * [suppressErrors](#suppresserrors)
|
---|
38 | * [throwErrorOnBrokenSymbolicLink](#throwerroronbrokensymboliclink)
|
---|
39 | * [Output control](#output-control)
|
---|
40 | * [absolute](#absolute)
|
---|
41 | * [markDirectories](#markdirectories)
|
---|
42 | * [objectMode](#objectmode)
|
---|
43 | * [onlyDirectories](#onlydirectories)
|
---|
44 | * [onlyFiles](#onlyfiles)
|
---|
45 | * [stats](#stats)
|
---|
46 | * [unique](#unique)
|
---|
47 | * [Matching control](#matching-control)
|
---|
48 | * [braceExpansion](#braceexpansion)
|
---|
49 | * [caseSensitiveMatch](#casesensitivematch)
|
---|
50 | * [dot](#dot)
|
---|
51 | * [extglob](#extglob)
|
---|
52 | * [globstar](#globstar)
|
---|
53 | * [baseNameMatch](#basenamematch)
|
---|
54 | * [FAQ](#faq)
|
---|
55 | * [What is a static or dynamic pattern?](#what-is-a-static-or-dynamic-pattern)
|
---|
56 | * [How to write patterns on Windows?](#how-to-write-patterns-on-windows)
|
---|
57 | * [Why are parentheses match wrong?](#why-are-parentheses-match-wrong)
|
---|
58 | * [How to exclude directory from reading?](#how-to-exclude-directory-from-reading)
|
---|
59 | * [How to use UNC path?](#how-to-use-unc-path)
|
---|
60 | * [Compatible with `node-glob`?](#compatible-with-node-glob)
|
---|
61 | * [Benchmarks](#benchmarks)
|
---|
62 | * [Server](#server)
|
---|
63 | * [Nettop](#nettop)
|
---|
64 | * [Changelog](#changelog)
|
---|
65 | * [License](#license)
|
---|
66 |
|
---|
67 | </details>
|
---|
68 |
|
---|
69 | ## Highlights
|
---|
70 |
|
---|
71 | * Fast. Probably the fastest.
|
---|
72 | * Supports multiple and negative patterns.
|
---|
73 | * Synchronous, Promise and Stream API.
|
---|
74 | * Object mode. Can return more than just strings.
|
---|
75 | * Error-tolerant.
|
---|
76 |
|
---|
77 | ## Donation
|
---|
78 |
|
---|
79 | Do you like this project? Support it by donating, creating an issue or pull request.
|
---|
80 |
|
---|
81 | [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)][paypal_mrmlnc]
|
---|
82 |
|
---|
83 | ## Old and modern mode
|
---|
84 |
|
---|
85 | This package works in two modes, depending on the environment in which it is used.
|
---|
86 |
|
---|
87 | * **Old mode**. Node.js below 10.10 or when the [`stats`](#stats) option is *enabled*.
|
---|
88 | * **Modern mode**. Node.js 10.10+ and the [`stats`](#stats) option is *disabled*.
|
---|
89 |
|
---|
90 | The modern mode is faster. Learn more about the [internal mechanism][nodelib_fs_scandir_old_and_modern_modern].
|
---|
91 |
|
---|
92 | ## Pattern syntax
|
---|
93 |
|
---|
94 | > :warning: Always use forward-slashes in glob expressions (patterns and [`ignore`](#ignore) option). Use backslashes for escaping characters.
|
---|
95 |
|
---|
96 | There is more than one form of syntax: basic and advanced. Below is a brief overview of the supported features. Also pay attention to our [FAQ](#faq).
|
---|
97 |
|
---|
98 | > :book: This package uses a [`micromatch`][micromatch] as a library for pattern matching.
|
---|
99 |
|
---|
100 | ### Basic syntax
|
---|
101 |
|
---|
102 | * An asterisk (`*`) — matches everything except slashes (path separators), hidden files (names starting with `.`).
|
---|
103 | * A double star or globstar (`**`) — matches zero or more directories.
|
---|
104 | * Question mark (`?`) – matches any single character except slashes (path separators).
|
---|
105 | * Sequence (`[seq]`) — matches any character in sequence.
|
---|
106 |
|
---|
107 | > :book: A few additional words about the [basic matching behavior][picomatch_matching_behavior].
|
---|
108 |
|
---|
109 | Some examples:
|
---|
110 |
|
---|
111 | * `src/**/*.js` — matches all files in the `src` directory (any level of nesting) that have the `.js` extension.
|
---|
112 | * `src/*.??` — matches all files in the `src` directory (only first level of nesting) that have a two-character extension.
|
---|
113 | * `file-[01].js` — matches files: `file-0.js`, `file-1.js`.
|
---|
114 |
|
---|
115 | ### Advanced syntax
|
---|
116 |
|
---|
117 | * [Escapes characters][micromatch_backslashes] (`\\`) — matching special characters (`$^*+?()[]`) as literals.
|
---|
118 | * [POSIX character classes][picomatch_posix_brackets] (`[[:digit:]]`).
|
---|
119 | * [Extended globs][micromatch_extglobs] (`?(pattern-list)`).
|
---|
120 | * [Bash style brace expansions][micromatch_braces] (`{}`).
|
---|
121 | * [Regexp character classes][micromatch_regex_character_classes] (`[1-5]`).
|
---|
122 | * [Regex groups][regular_expressions_brackets] (`(a|b)`).
|
---|
123 |
|
---|
124 | > :book: A few additional words about the [advanced matching behavior][micromatch_extended_globbing].
|
---|
125 |
|
---|
126 | Some examples:
|
---|
127 |
|
---|
128 | * `src/**/*.{css,scss}` — matches all files in the `src` directory (any level of nesting) that have the `.css` or `.scss` extension.
|
---|
129 | * `file-[[:digit:]].js` — matches files: `file-0.js`, `file-1.js`, …, `file-9.js`.
|
---|
130 | * `file-{1..3}.js` — matches files: `file-1.js`, `file-2.js`, `file-3.js`.
|
---|
131 | * `file-(1|2)` — matches files: `file-1.js`, `file-2.js`.
|
---|
132 |
|
---|
133 | ## Installation
|
---|
134 |
|
---|
135 | ```console
|
---|
136 | npm install fast-glob
|
---|
137 | ```
|
---|
138 |
|
---|
139 | ## API
|
---|
140 |
|
---|
141 | ### Asynchronous
|
---|
142 |
|
---|
143 | ```js
|
---|
144 | fg(patterns, [options])
|
---|
145 | ```
|
---|
146 |
|
---|
147 | Returns a `Promise` with an array of matching entries.
|
---|
148 |
|
---|
149 | ```js
|
---|
150 | const fg = require('fast-glob');
|
---|
151 |
|
---|
152 | const entries = await fg(['.editorconfig', '**/index.js'], { dot: true });
|
---|
153 |
|
---|
154 | // ['.editorconfig', 'services/index.js']
|
---|
155 | ```
|
---|
156 |
|
---|
157 | ### Synchronous
|
---|
158 |
|
---|
159 | ```js
|
---|
160 | fg.sync(patterns, [options])
|
---|
161 | ```
|
---|
162 |
|
---|
163 | Returns an array of matching entries.
|
---|
164 |
|
---|
165 | ```js
|
---|
166 | const fg = require('fast-glob');
|
---|
167 |
|
---|
168 | const entries = fg.sync(['.editorconfig', '**/index.js'], { dot: true });
|
---|
169 |
|
---|
170 | // ['.editorconfig', 'services/index.js']
|
---|
171 | ```
|
---|
172 |
|
---|
173 | ### Stream
|
---|
174 |
|
---|
175 | ```js
|
---|
176 | fg.stream(patterns, [options])
|
---|
177 | ```
|
---|
178 |
|
---|
179 | Returns a [`ReadableStream`][node_js_stream_readable_streams] when the `data` event will be emitted with matching entry.
|
---|
180 |
|
---|
181 | ```js
|
---|
182 | const fg = require('fast-glob');
|
---|
183 |
|
---|
184 | const stream = fg.stream(['.editorconfig', '**/index.js'], { dot: true });
|
---|
185 |
|
---|
186 | for await (const entry of stream) {
|
---|
187 | // .editorconfig
|
---|
188 | // services/index.js
|
---|
189 | }
|
---|
190 | ```
|
---|
191 |
|
---|
192 | #### patterns
|
---|
193 |
|
---|
194 | * Required: `true`
|
---|
195 | * Type: `string | string[]`
|
---|
196 |
|
---|
197 | Any correct pattern(s).
|
---|
198 |
|
---|
199 | > :1234: [Pattern syntax](#pattern-syntax)
|
---|
200 | >
|
---|
201 | > :warning: This package does not respect the order of patterns. First, all the negative patterns are applied, and only then the positive patterns. If you want to get a certain order of records, use sorting or split calls.
|
---|
202 |
|
---|
203 | #### [options]
|
---|
204 |
|
---|
205 | * Required: `false`
|
---|
206 | * Type: [`Options`](#options-3)
|
---|
207 |
|
---|
208 | See [Options](#options-3) section.
|
---|
209 |
|
---|
210 | ### Helpers
|
---|
211 |
|
---|
212 | #### `generateTasks(patterns, [options])`
|
---|
213 |
|
---|
214 | Returns the internal representation of patterns ([`Task`](./src/managers/tasks.ts) is a combining patterns by base directory).
|
---|
215 |
|
---|
216 | ```js
|
---|
217 | fg.generateTasks('*');
|
---|
218 |
|
---|
219 | [{
|
---|
220 | base: '.', // Parent directory for all patterns inside this task
|
---|
221 | dynamic: true, // Dynamic or static patterns are in this task
|
---|
222 | patterns: ['*'],
|
---|
223 | positive: ['*'],
|
---|
224 | negative: []
|
---|
225 | }]
|
---|
226 | ```
|
---|
227 |
|
---|
228 | ##### patterns
|
---|
229 |
|
---|
230 | * Required: `true`
|
---|
231 | * Type: `string | string[]`
|
---|
232 |
|
---|
233 | Any correct pattern(s).
|
---|
234 |
|
---|
235 | ##### [options]
|
---|
236 |
|
---|
237 | * Required: `false`
|
---|
238 | * Type: [`Options`](#options-3)
|
---|
239 |
|
---|
240 | See [Options](#options-3) section.
|
---|
241 |
|
---|
242 | #### `isDynamicPattern(pattern, [options])`
|
---|
243 |
|
---|
244 | Returns `true` if the passed pattern is a dynamic pattern.
|
---|
245 |
|
---|
246 | > :1234: [What is a static or dynamic pattern?](#what-is-a-static-or-dynamic-pattern)
|
---|
247 |
|
---|
248 | ```js
|
---|
249 | fg.isDynamicPattern('*'); // true
|
---|
250 | fg.isDynamicPattern('abc'); // false
|
---|
251 | ```
|
---|
252 |
|
---|
253 | ##### pattern
|
---|
254 |
|
---|
255 | * Required: `true`
|
---|
256 | * Type: `string`
|
---|
257 |
|
---|
258 | Any correct pattern.
|
---|
259 |
|
---|
260 | ##### [options]
|
---|
261 |
|
---|
262 | * Required: `false`
|
---|
263 | * Type: [`Options`](#options-3)
|
---|
264 |
|
---|
265 | See [Options](#options-3) section.
|
---|
266 |
|
---|
267 | #### `escapePath(pattern)`
|
---|
268 |
|
---|
269 | Returns a path with escaped special characters (`*?|(){}[]`, `!` at the beginning of line, `@+!` before the opening parenthesis).
|
---|
270 |
|
---|
271 | ```js
|
---|
272 | fg.escapePath('!abc'); // \\!abc
|
---|
273 | fg.escapePath('C:/Program Files (x86)'); // C:/Program Files \\(x86\\)
|
---|
274 | ```
|
---|
275 |
|
---|
276 | ##### pattern
|
---|
277 |
|
---|
278 | * Required: `true`
|
---|
279 | * Type: `string`
|
---|
280 |
|
---|
281 | Any string, for example, a path to a file.
|
---|
282 |
|
---|
283 | ## Options
|
---|
284 |
|
---|
285 | ### Common options
|
---|
286 |
|
---|
287 | #### concurrency
|
---|
288 |
|
---|
289 | * Type: `number`
|
---|
290 | * Default: `os.cpus().length`
|
---|
291 |
|
---|
292 | Specifies the maximum number of concurrent requests from a reader to read directories.
|
---|
293 |
|
---|
294 | > :book: The higher the number, the higher the performance and load on the file system. If you want to read in quiet mode, set the value to a comfortable number or `1`.
|
---|
295 |
|
---|
296 | #### cwd
|
---|
297 |
|
---|
298 | * Type: `string`
|
---|
299 | * Default: `process.cwd()`
|
---|
300 |
|
---|
301 | The current working directory in which to search.
|
---|
302 |
|
---|
303 | #### deep
|
---|
304 |
|
---|
305 | * Type: `number`
|
---|
306 | * Default: `Infinity`
|
---|
307 |
|
---|
308 | Specifies the maximum depth of a read directory relative to the start directory.
|
---|
309 |
|
---|
310 | For example, you have the following tree:
|
---|
311 |
|
---|
312 | ```js
|
---|
313 | dir/
|
---|
314 | └── one/ // 1
|
---|
315 | └── two/ // 2
|
---|
316 | └── file.js // 3
|
---|
317 | ```
|
---|
318 |
|
---|
319 | ```js
|
---|
320 | // With base directory
|
---|
321 | fg.sync('dir/**', { onlyFiles: false, deep: 1 }); // ['dir/one']
|
---|
322 | fg.sync('dir/**', { onlyFiles: false, deep: 2 }); // ['dir/one', 'dir/one/two']
|
---|
323 |
|
---|
324 | // With cwd option
|
---|
325 | fg.sync('**', { onlyFiles: false, cwd: 'dir', deep: 1 }); // ['one']
|
---|
326 | fg.sync('**', { onlyFiles: false, cwd: 'dir', deep: 2 }); // ['one', 'one/two']
|
---|
327 | ```
|
---|
328 |
|
---|
329 | > :book: If you specify a pattern with some base directory, this directory will not participate in the calculation of the depth of the found directories. Think of it as a [`cwd`](#cwd) option.
|
---|
330 |
|
---|
331 | #### followSymbolicLinks
|
---|
332 |
|
---|
333 | * Type: `boolean`
|
---|
334 | * Default: `true`
|
---|
335 |
|
---|
336 | Indicates whether to traverse descendants of symbolic link directories when expanding `**` patterns.
|
---|
337 |
|
---|
338 | > :book: Note that this option does not affect the base directory of the pattern. For example, if `./a` is a symlink to directory `./b` and you specified `['./a**', './b/**']` patterns, then directory `./a` will still be read.
|
---|
339 |
|
---|
340 | > :book: If the [`stats`](#stats) option is specified, the information about the symbolic link (`fs.lstat`) will be replaced with information about the entry (`fs.stat`) behind it.
|
---|
341 |
|
---|
342 | #### fs
|
---|
343 |
|
---|
344 | * Type: `FileSystemAdapter`
|
---|
345 | * Default: `fs.*`
|
---|
346 |
|
---|
347 | Custom implementation of methods for working with the file system.
|
---|
348 |
|
---|
349 | ```ts
|
---|
350 | export interface FileSystemAdapter {
|
---|
351 | lstat?: typeof fs.lstat;
|
---|
352 | stat?: typeof fs.stat;
|
---|
353 | lstatSync?: typeof fs.lstatSync;
|
---|
354 | statSync?: typeof fs.statSync;
|
---|
355 | readdir?: typeof fs.readdir;
|
---|
356 | readdirSync?: typeof fs.readdirSync;
|
---|
357 | }
|
---|
358 | ```
|
---|
359 |
|
---|
360 | #### ignore
|
---|
361 |
|
---|
362 | * Type: `string[]`
|
---|
363 | * Default: `[]`
|
---|
364 |
|
---|
365 | An array of glob patterns to exclude matches. This is an alternative way to use negative patterns.
|
---|
366 |
|
---|
367 | ```js
|
---|
368 | dir/
|
---|
369 | ├── package-lock.json
|
---|
370 | └── package.json
|
---|
371 | ```
|
---|
372 |
|
---|
373 | ```js
|
---|
374 | fg.sync(['*.json', '!package-lock.json']); // ['package.json']
|
---|
375 | fg.sync('*.json', { ignore: ['package-lock.json'] }); // ['package.json']
|
---|
376 | ```
|
---|
377 |
|
---|
378 | #### suppressErrors
|
---|
379 |
|
---|
380 | * Type: `boolean`
|
---|
381 | * Default: `false`
|
---|
382 |
|
---|
383 | By default this package suppress only `ENOENT` errors. Set to `true` to suppress any error.
|
---|
384 |
|
---|
385 | > :book: Can be useful when the directory has entries with a special level of access.
|
---|
386 |
|
---|
387 | #### throwErrorOnBrokenSymbolicLink
|
---|
388 |
|
---|
389 | * Type: `boolean`
|
---|
390 | * Default: `false`
|
---|
391 |
|
---|
392 | Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`.
|
---|
393 |
|
---|
394 | > :book: This option has no effect on errors when reading the symbolic link directory.
|
---|
395 |
|
---|
396 | ### Output control
|
---|
397 |
|
---|
398 | #### absolute
|
---|
399 |
|
---|
400 | * Type: `boolean`
|
---|
401 | * Default: `false`
|
---|
402 |
|
---|
403 | Return the absolute path for entries.
|
---|
404 |
|
---|
405 | ```js
|
---|
406 | fg.sync('*.js', { absolute: false }); // ['index.js']
|
---|
407 | fg.sync('*.js', { absolute: true }); // ['/home/user/index.js']
|
---|
408 | ```
|
---|
409 |
|
---|
410 | > :book: This option is required if you want to use negative patterns with absolute path, for example, `!${__dirname}/*.js`.
|
---|
411 |
|
---|
412 | #### markDirectories
|
---|
413 |
|
---|
414 | * Type: `boolean`
|
---|
415 | * Default: `false`
|
---|
416 |
|
---|
417 | Mark the directory path with the final slash.
|
---|
418 |
|
---|
419 | ```js
|
---|
420 | fg.sync('*', { onlyFiles: false, markDirectories: false }); // ['index.js', 'controllers']
|
---|
421 | fg.sync('*', { onlyFiles: false, markDirectories: true }); // ['index.js', 'controllers/']
|
---|
422 | ```
|
---|
423 |
|
---|
424 | #### objectMode
|
---|
425 |
|
---|
426 | * Type: `boolean`
|
---|
427 | * Default: `false`
|
---|
428 |
|
---|
429 | Returns objects (instead of strings) describing entries.
|
---|
430 |
|
---|
431 | ```js
|
---|
432 | fg.sync('*', { objectMode: false }); // ['src/index.js']
|
---|
433 | fg.sync('*', { objectMode: true }); // [{ name: 'index.js', path: 'src/index.js', dirent: <fs.Dirent> }]
|
---|
434 | ```
|
---|
435 |
|
---|
436 | The object has the following fields:
|
---|
437 |
|
---|
438 | * name (`string`) — the last part of the path (basename)
|
---|
439 | * path (`string`) — full path relative to the pattern base directory
|
---|
440 | * dirent ([`fs.Dirent`][node_js_fs_class_fs_dirent]) — instance of `fs.Direct`
|
---|
441 |
|
---|
442 | > :book: An object is an internal representation of entry, so getting it does not affect performance.
|
---|
443 |
|
---|
444 | #### onlyDirectories
|
---|
445 |
|
---|
446 | * Type: `boolean`
|
---|
447 | * Default: `false`
|
---|
448 |
|
---|
449 | Return only directories.
|
---|
450 |
|
---|
451 | ```js
|
---|
452 | fg.sync('*', { onlyDirectories: false }); // ['index.js', 'src']
|
---|
453 | fg.sync('*', { onlyDirectories: true }); // ['src']
|
---|
454 | ```
|
---|
455 |
|
---|
456 | > :book: If `true`, the [`onlyFiles`](#onlyfiles) option is automatically `false`.
|
---|
457 |
|
---|
458 | #### onlyFiles
|
---|
459 |
|
---|
460 | * Type: `boolean`
|
---|
461 | * Default: `true`
|
---|
462 |
|
---|
463 | Return only files.
|
---|
464 |
|
---|
465 | ```js
|
---|
466 | fg.sync('*', { onlyFiles: false }); // ['index.js', 'src']
|
---|
467 | fg.sync('*', { onlyFiles: true }); // ['index.js']
|
---|
468 | ```
|
---|
469 |
|
---|
470 | #### stats
|
---|
471 |
|
---|
472 | * Type: `boolean`
|
---|
473 | * Default: `false`
|
---|
474 |
|
---|
475 | Enables an [object mode](#objectmode) with an additional field:
|
---|
476 |
|
---|
477 | * stats ([`fs.Stats`][node_js_fs_class_fs_stats]) — instance of `fs.Stats`
|
---|
478 |
|
---|
479 | ```js
|
---|
480 | fg.sync('*', { stats: false }); // ['src/index.js']
|
---|
481 | fg.sync('*', { stats: true }); // [{ name: 'index.js', path: 'src/index.js', dirent: <fs.Dirent>, stats: <fs.Stats> }]
|
---|
482 | ```
|
---|
483 |
|
---|
484 | > :book: Returns `fs.stat` instead of `fs.lstat` for symbolic links when the [`followSymbolicLinks`](#followsymboliclinks) option is specified.
|
---|
485 | >
|
---|
486 | > :warning: Unlike [object mode](#objectmode) this mode requires additional calls to the file system. On average, this mode is slower at least twice. See [old and modern mode](#old-and-modern-mode) for more details.
|
---|
487 |
|
---|
488 | #### unique
|
---|
489 |
|
---|
490 | * Type: `boolean`
|
---|
491 | * Default: `true`
|
---|
492 |
|
---|
493 | Ensures that the returned entries are unique.
|
---|
494 |
|
---|
495 | ```js
|
---|
496 | fg.sync(['*.json', 'package.json'], { unique: false }); // ['package.json', 'package.json']
|
---|
497 | fg.sync(['*.json', 'package.json'], { unique: true }); // ['package.json']
|
---|
498 | ```
|
---|
499 |
|
---|
500 | If `true` and similar entries are found, the result is the first found.
|
---|
501 |
|
---|
502 | ### Matching control
|
---|
503 |
|
---|
504 | #### braceExpansion
|
---|
505 |
|
---|
506 | * Type: `boolean`
|
---|
507 | * Default: `true`
|
---|
508 |
|
---|
509 | Enables Bash-like brace expansion.
|
---|
510 |
|
---|
511 | > :1234: [Syntax description][bash_hackers_syntax_expansion_brace] or more [detailed description][micromatch_braces].
|
---|
512 |
|
---|
513 | ```js
|
---|
514 | dir/
|
---|
515 | ├── abd
|
---|
516 | ├── acd
|
---|
517 | └── a{b,c}d
|
---|
518 | ```
|
---|
519 |
|
---|
520 | ```js
|
---|
521 | fg.sync('a{b,c}d', { braceExpansion: false }); // ['a{b,c}d']
|
---|
522 | fg.sync('a{b,c}d', { braceExpansion: true }); // ['abd', 'acd']
|
---|
523 | ```
|
---|
524 |
|
---|
525 | #### caseSensitiveMatch
|
---|
526 |
|
---|
527 | * Type: `boolean`
|
---|
528 | * Default: `true`
|
---|
529 |
|
---|
530 | Enables a [case-sensitive][wikipedia_case_sensitivity] mode for matching files.
|
---|
531 |
|
---|
532 | ```js
|
---|
533 | dir/
|
---|
534 | ├── file.txt
|
---|
535 | └── File.txt
|
---|
536 | ```
|
---|
537 |
|
---|
538 | ```js
|
---|
539 | fg.sync('file.txt', { caseSensitiveMatch: false }); // ['file.txt', 'File.txt']
|
---|
540 | fg.sync('file.txt', { caseSensitiveMatch: true }); // ['file.txt']
|
---|
541 | ```
|
---|
542 |
|
---|
543 | #### dot
|
---|
544 |
|
---|
545 | * Type: `boolean`
|
---|
546 | * Default: `false`
|
---|
547 |
|
---|
548 | Allow patterns to match entries that begin with a period (`.`).
|
---|
549 |
|
---|
550 | > :book: Note that an explicit dot in a portion of the pattern will always match dot files.
|
---|
551 |
|
---|
552 | ```js
|
---|
553 | dir/
|
---|
554 | ├── .editorconfig
|
---|
555 | └── package.json
|
---|
556 | ```
|
---|
557 |
|
---|
558 | ```js
|
---|
559 | fg.sync('*', { dot: false }); // ['package.json']
|
---|
560 | fg.sync('*', { dot: true }); // ['.editorconfig', 'package.json']
|
---|
561 | ```
|
---|
562 |
|
---|
563 | #### extglob
|
---|
564 |
|
---|
565 | * Type: `boolean`
|
---|
566 | * Default: `true`
|
---|
567 |
|
---|
568 | Enables Bash-like `extglob` functionality.
|
---|
569 |
|
---|
570 | > :1234: [Syntax description][micromatch_extglobs].
|
---|
571 |
|
---|
572 | ```js
|
---|
573 | dir/
|
---|
574 | ├── README.md
|
---|
575 | └── package.json
|
---|
576 | ```
|
---|
577 |
|
---|
578 | ```js
|
---|
579 | fg.sync('*.+(json|md)', { extglob: false }); // []
|
---|
580 | fg.sync('*.+(json|md)', { extglob: true }); // ['README.md', 'package.json']
|
---|
581 | ```
|
---|
582 |
|
---|
583 | #### globstar
|
---|
584 |
|
---|
585 | * Type: `boolean`
|
---|
586 | * Default: `true`
|
---|
587 |
|
---|
588 | Enables recursively repeats a pattern containing `**`. If `false`, `**` behaves exactly like `*`.
|
---|
589 |
|
---|
590 | ```js
|
---|
591 | dir/
|
---|
592 | └── a
|
---|
593 | └── b
|
---|
594 | ```
|
---|
595 |
|
---|
596 | ```js
|
---|
597 | fg.sync('**', { onlyFiles: false, globstar: false }); // ['a']
|
---|
598 | fg.sync('**', { onlyFiles: false, globstar: true }); // ['a', 'a/b']
|
---|
599 | ```
|
---|
600 |
|
---|
601 | #### baseNameMatch
|
---|
602 |
|
---|
603 | * Type: `boolean`
|
---|
604 | * Default: `false`
|
---|
605 |
|
---|
606 | If set to `true`, then patterns without slashes will be matched against the basename of the path if it contains slashes.
|
---|
607 |
|
---|
608 | ```js
|
---|
609 | dir/
|
---|
610 | └── one/
|
---|
611 | └── file.md
|
---|
612 | ```
|
---|
613 |
|
---|
614 | ```js
|
---|
615 | fg.sync('*.md', { baseNameMatch: false }); // []
|
---|
616 | fg.sync('*.md', { baseNameMatch: true }); // ['one/file.md']
|
---|
617 | ```
|
---|
618 |
|
---|
619 | ## FAQ
|
---|
620 |
|
---|
621 | ## What is a static or dynamic pattern?
|
---|
622 |
|
---|
623 | All patterns can be divided into two types:
|
---|
624 |
|
---|
625 | * **static**. A pattern is considered static if it can be used to get an entry on the file system without using matching mechanisms. For example, the `file.js` pattern is a static pattern because we can just verify that it exists on the file system.
|
---|
626 | * **dynamic**. A pattern is considered dynamic if it cannot be used directly to find occurrences without using a matching mechanisms. For example, the `*` pattern is a dynamic pattern because we cannot use this pattern directly.
|
---|
627 |
|
---|
628 | A pattern is considered dynamic if it contains the following characters (`…` — any characters or their absence) or options:
|
---|
629 |
|
---|
630 | * The [`caseSensitiveMatch`](#casesensitivematch) option is disabled
|
---|
631 | * `\\` (the escape character)
|
---|
632 | * `*`, `?`, `!` (at the beginning of line)
|
---|
633 | * `[…]`
|
---|
634 | * `(…|…)`
|
---|
635 | * `@(…)`, `!(…)`, `*(…)`, `?(…)`, `+(…)` (respects the [`extglob`](#extglob) option)
|
---|
636 | * `{…,…}`, `{…..…}` (respects the [`braceExpansion`](#braceexpansion) option)
|
---|
637 |
|
---|
638 | ## How to write patterns on Windows?
|
---|
639 |
|
---|
640 | Always use forward-slashes in glob expressions (patterns and [`ignore`](#ignore) option). Use backslashes for escaping characters. With the [`cwd`](#cwd) option use a convenient format.
|
---|
641 |
|
---|
642 | **Bad**
|
---|
643 |
|
---|
644 | ```ts
|
---|
645 | [
|
---|
646 | 'directory\\*',
|
---|
647 | path.join(process.cwd(), '**')
|
---|
648 | ]
|
---|
649 | ```
|
---|
650 |
|
---|
651 | **Good**
|
---|
652 |
|
---|
653 | ```ts
|
---|
654 | [
|
---|
655 | 'directory/*',
|
---|
656 | path.join(process.cwd(), '**').replace(/\\/g, '/')
|
---|
657 | ]
|
---|
658 | ```
|
---|
659 |
|
---|
660 | > :book: Use the [`normalize-path`][npm_normalize_path] or the [`unixify`][npm_unixify] package to convert Windows-style path to a Unix-style path.
|
---|
661 |
|
---|
662 | Read more about [matching with backslashes][micromatch_backslashes].
|
---|
663 |
|
---|
664 | ## Why are parentheses match wrong?
|
---|
665 |
|
---|
666 | ```js
|
---|
667 | dir/
|
---|
668 | └── (special-*file).txt
|
---|
669 | ```
|
---|
670 |
|
---|
671 | ```js
|
---|
672 | fg.sync(['(special-*file).txt']) // []
|
---|
673 | ```
|
---|
674 |
|
---|
675 | Refers to Bash. You need to escape special characters:
|
---|
676 |
|
---|
677 | ```js
|
---|
678 | fg.sync(['\\(special-*file\\).txt']) // ['(special-*file).txt']
|
---|
679 | ```
|
---|
680 |
|
---|
681 | Read more about [matching special characters as literals][picomatch_matching_special_characters_as_literals].
|
---|
682 |
|
---|
683 | ## How to exclude directory from reading?
|
---|
684 |
|
---|
685 | You can use a negative pattern like this: `!**/node_modules` or `!**/node_modules/**`. Also you can use [`ignore`](#ignore) option. Just look at the example below.
|
---|
686 |
|
---|
687 | ```js
|
---|
688 | first/
|
---|
689 | ├── file.md
|
---|
690 | └── second/
|
---|
691 | └── file.txt
|
---|
692 | ```
|
---|
693 |
|
---|
694 | If you don't want to read the `second` directory, you must write the following pattern: `!**/second` or `!**/second/**`.
|
---|
695 |
|
---|
696 | ```js
|
---|
697 | fg.sync(['**/*.md', '!**/second']); // ['first/file.md']
|
---|
698 | fg.sync(['**/*.md'], { ignore: ['**/second/**'] }); // ['first/file.md']
|
---|
699 | ```
|
---|
700 |
|
---|
701 | > :warning: When you write `!**/second/**/*` it means that the directory will be **read**, but all the entries will not be included in the results.
|
---|
702 |
|
---|
703 | You have to understand that if you write the pattern to exclude directories, then the directory will not be read under any circumstances.
|
---|
704 |
|
---|
705 | ## How to use UNC path?
|
---|
706 |
|
---|
707 | You cannot use [Uniform Naming Convention (UNC)][unc_path] paths as patterns (due to syntax), but you can use them as [`cwd`](#cwd) directory.
|
---|
708 |
|
---|
709 | ```ts
|
---|
710 | fg.sync('*', { cwd: '\\\\?\\C:\\Python27' /* or //?/C:/Python27 */ });
|
---|
711 | fg.sync('Python27/*', { cwd: '\\\\?\\C:\\' /* or //?/C:/ */ });
|
---|
712 | ```
|
---|
713 |
|
---|
714 | ## Compatible with `node-glob`?
|
---|
715 |
|
---|
716 | | node-glob | fast-glob |
|
---|
717 | | :----------: | :-------: |
|
---|
718 | | `cwd` | [`cwd`](#cwd) |
|
---|
719 | | `root` | – |
|
---|
720 | | `dot` | [`dot`](#dot) |
|
---|
721 | | `nomount` | – |
|
---|
722 | | `mark` | [`markDirectories`](#markdirectories) |
|
---|
723 | | `nosort` | – |
|
---|
724 | | `nounique` | [`unique`](#unique) |
|
---|
725 | | `nobrace` | [`braceExpansion`](#braceexpansion) |
|
---|
726 | | `noglobstar` | [`globstar`](#globstar) |
|
---|
727 | | `noext` | [`extglob`](#extglob) |
|
---|
728 | | `nocase` | [`caseSensitiveMatch`](#casesensitivematch) |
|
---|
729 | | `matchBase` | [`baseNameMatch`](#basenamematch) |
|
---|
730 | | `nodir` | [`onlyFiles`](#onlyfiles) |
|
---|
731 | | `ignore` | [`ignore`](#ignore) |
|
---|
732 | | `follow` | [`followSymbolicLinks`](#followsymboliclinks) |
|
---|
733 | | `realpath` | – |
|
---|
734 | | `absolute` | [`absolute`](#absolute) |
|
---|
735 |
|
---|
736 | ## Benchmarks
|
---|
737 |
|
---|
738 | ### Server
|
---|
739 |
|
---|
740 | Link: [Vultr Bare Metal][vultr_pricing_baremetal]
|
---|
741 |
|
---|
742 | * Processor: E3-1270v6 (8 CPU)
|
---|
743 | * RAM: 32GB
|
---|
744 | * Disk: SSD ([Intel DC S3520 SSDSC2BB240G7][intel_ssd])
|
---|
745 |
|
---|
746 | You can see results [here][github_gist_benchmark_server] for latest release.
|
---|
747 |
|
---|
748 | ### Nettop
|
---|
749 |
|
---|
750 | Link: [Zotac bi323][zotac_bi323]
|
---|
751 |
|
---|
752 | * Processor: Intel N3150 (4 CPU)
|
---|
753 | * RAM: 8GB
|
---|
754 | * Disk: SSD ([Silicon Power SP060GBSS3S55S25][silicon_power_ssd])
|
---|
755 |
|
---|
756 | You can see results [here][github_gist_benchmark_nettop] for latest release.
|
---|
757 |
|
---|
758 | ## Changelog
|
---|
759 |
|
---|
760 | See the [Releases section of our GitHub project][github_releases] for changelog for each release version.
|
---|
761 |
|
---|
762 | ## License
|
---|
763 |
|
---|
764 | This software is released under the terms of the MIT license.
|
---|
765 |
|
---|
766 | [bash_hackers_syntax_expansion_brace]: https://wiki.bash-hackers.org/syntax/expansion/brace
|
---|
767 | [github_gist_benchmark_nettop]: https://gist.github.com/mrmlnc/f06246b197f53c356895fa35355a367c#file-fg-benchmark-nettop-product-txt
|
---|
768 | [github_gist_benchmark_server]: https://gist.github.com/mrmlnc/f06246b197f53c356895fa35355a367c#file-fg-benchmark-server-product-txt
|
---|
769 | [github_releases]: https://github.com/mrmlnc/fast-glob/releases
|
---|
770 | [glob_definition]: https://en.wikipedia.org/wiki/Glob_(programming)
|
---|
771 | [glob_linux_man]: http://man7.org/linux/man-pages/man3/glob.3.html
|
---|
772 | [intel_ssd]: https://ark.intel.com/content/www/us/en/ark/products/93012/intel-ssd-dc-s3520-series-240gb-2-5in-sata-6gb-s-3d1-mlc.html
|
---|
773 | [micromatch_backslashes]: https://github.com/micromatch/micromatch#backslashes
|
---|
774 | [micromatch_braces]: https://github.com/micromatch/braces
|
---|
775 | [micromatch_extended_globbing]: https://github.com/micromatch/micromatch#extended-globbing
|
---|
776 | [micromatch_extglobs]: https://github.com/micromatch/micromatch#extglobs
|
---|
777 | [micromatch_regex_character_classes]: https://github.com/micromatch/micromatch#regex-character-classes
|
---|
778 | [micromatch]: https://github.com/micromatch/micromatch
|
---|
779 | [node_js_fs_class_fs_dirent]: https://nodejs.org/api/fs.html#fs_class_fs_dirent
|
---|
780 | [node_js_fs_class_fs_stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats
|
---|
781 | [node_js_stream_readable_streams]: https://nodejs.org/api/stream.html#stream_readable_streams
|
---|
782 | [node_js]: https://nodejs.org/en
|
---|
783 | [nodelib_fs_scandir_old_and_modern_modern]: https://github.com/nodelib/nodelib/blob/master/packages/fs/fs.scandir/README.md#old-and-modern-mode
|
---|
784 | [npm_normalize_path]: https://www.npmjs.com/package/normalize-path
|
---|
785 | [npm_unixify]: https://www.npmjs.com/package/unixify
|
---|
786 | [paypal_mrmlnc]:https://paypal.me/mrmlnc
|
---|
787 | [picomatch_matching_behavior]: https://github.com/micromatch/picomatch#matching-behavior-vs-bash
|
---|
788 | [picomatch_matching_special_characters_as_literals]: https://github.com/micromatch/picomatch#matching-special-characters-as-literals
|
---|
789 | [picomatch_posix_brackets]: https://github.com/micromatch/picomatch#posix-brackets
|
---|
790 | [regular_expressions_brackets]: https://www.regular-expressions.info/brackets.html
|
---|
791 | [silicon_power_ssd]: https://www.silicon-power.com/web/product-1
|
---|
792 | [unc_path]: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/62e862f4-2a51-452e-8eeb-dc4ff5ee33cc
|
---|
793 | [vultr_pricing_baremetal]: https://www.vultr.com/pricing/baremetal
|
---|
794 | [wikipedia_case_sensitivity]: https://en.wikipedia.org/wiki/Case_sensitivity
|
---|
795 | [zotac_bi323]: https://www.zotac.com/ee/product/mini_pcs/zbox-bi323
|
---|