[6a3a178] | 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
|
---|