UNPKG

9.47 kBMarkdownView Raw
1# :rocket: fast-glob
2
3> Is a faster [`node-glob`](https://github.com/isaacs/node-glob) alternative.
4
5[![Build Status](https://travis-ci.org/mrmlnc/fast-glob.svg?branch=master)](https://travis-ci.org/mrmlnc/fast-glob)
6[![Build status](https://ci.appveyor.com/api/projects/status/i4xqijtq26qf6o9d?svg=true)](https://ci.appveyor.com/project/mrmlnc/fast-glob)
7
8## :bulb: Highlights
9
10 * :rocket: Fast by using Streams and Promises. Used [readdir-enhanced](https://github.com/BigstickCarpet/readdir-enhanced) and [micromatch](https://github.com/jonschlinkert/micromatch).
11 * :beginner: User-friendly, since it supports multiple and negated patterns (`['*', '!*.md']`).
12 * :vertical_traffic_light: Rational, because it doesn't read excluded directories (`!**/node_modules/**`).
13 * :gear: Universal, because it supports Synchronous, Promise and Stream API.
14 * :money_with_wings: Economy, because it provides `fs.Stats` for matched path if you wanted.
15
16## Donate
17
18If you want to thank me, or promote your Issue.
19
20[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/mrmlnc)
21
22> Sorry, but I have work and support for packages requires some time after work. I will be glad of your support and PR's.
23
24## Install
25
26```
27$ npm install --save fast-glob
28```
29
30## Usage
31
32#### Asynchronous
33
34```js
35const fg = require('fast-glob');
36
37fg(['src/**/*.js', '!src/**/*.spec.js']).then((entries) => console.log(entries));
38fg.async(['src/**/*.js', '!src/**/*.spec.js']).then((entries) => console.log(entries));
39```
40
41#### Synchronous
42
43```js
44const fg = require('fast-glob');
45
46const entries = fg.sync(['src/**/*.js', '!src/**/*.spec.js']);
47console.log(entries);
48```
49
50#### Stream
51
52```js
53const fg = require('fast-glob');
54
55const stream = fg.stream(['src/**/*.js', '!src/**/*.spec.js']);
56
57const entries = [];
58
59stream.on('data', (entry) => entries.push(entry));
60stream.once('error', console.log);
61stream.once('end', () => console.log(entries));
62```
63
64## API
65
66### fg(patterns, [options])
67### fg.async(patterns, [options])
68
69Returns a `Promise<Array>` of matching entries.
70
71#### patterns
72
73 * Type: `string|string[]`
74
75This package does not respect the order of patterns. First, all the negative patterns are applied, and only then the positive patterns.
76
77#### options
78
79 * Type: `Object`
80
81See [options](#options-1) section for more detailed information.
82
83### fg.sync(patterns, [options])
84
85Returns a `Array` of matching entries.
86
87### fg.stream(patterns, [options])
88
89Returns a [`ReadableStream`](https://nodejs.org/api/stream.html#stream_readable_streams).
90
91### fg.generateTasks(patterns, [options])
92
93Return a set of tasks based on provided patterns. All tasks satisfy the `Task` interface:
94
95```ts
96interface Task {
97 /**
98 * Parent directory for all patterns inside this task.
99 */
100 base: string;
101 /**
102 * Dynamic or static patterns are in this task.
103 */
104 dynamic: boolean;
105 /**
106 * All patterns.
107 */
108 patterns: string[];
109 /**
110 * Only positive patterns.
111 */
112 positive: string[];
113 /**
114 * Only negative patterns without ! symbol.
115 */
116 negative: string[];
117}
118```
119
120## Options
121
122#### cwd
123
124 * Type: `string`
125 * Default: `process.cwd()`
126
127The current working directory in which to search.
128
129#### deep
130
131 * Type: `number|boolean`
132 * Default: `true`
133
134The 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.
135
136#### ignore
137
138 * Type: `string[]`
139 * Default: `[]`
140
141An array of glob patterns to exclude matches.
142
143#### dot
144
145 * Type: `boolean`
146 * Default: `false`
147
148Allow patterns to match filenames starting with a period (files & directories), even if the pattern does not explicitly have a period in that spot.
149
150#### stats
151
152 * Type: `number|boolean`
153 * Default: `false`
154
155Return `fs.Stats` with `path` property instead of file path.
156
157#### onlyFiles
158
159 * Type: `boolean`
160 * Default: `true`
161
162Return only files.
163
164#### onlyDirectories
165
166 * Type: `boolean`
167 * Default: `false`
168
169Return only directories.
170
171#### followSymlinkedDirectories
172
173 * Type: `boolean`
174 * Default: `true`
175
176Follow symlinked directories when expanding `**` patterns.
177
178#### unique
179
180 * Type: `boolean`
181 * Default: `true`
182
183Prevent duplicate results.
184
185#### markDirectories
186
187 * Type: `boolean`
188 * Default: `false`
189
190Add a `/` character to directory entries.
191
192#### absolute
193
194 * Type: `boolean`
195 * Default: `false`
196
197Return absolute paths for matched entries.
198
199#### nobrace
200
201 * Type: `boolean`
202 * Default: `false`
203
204Disable expansion of brace patterns (`{a,b}`, `{1..3}`).
205
206#### brace
207
208 * Type: `boolean`
209 * Default: `true`
210
211The [`nobrace`](#nobrace) option without double-negation. This option has a higher priority then `nobrace`.
212
213#### noglobstar
214
215 * Type: `boolean`
216 * Default: `false`
217
218Disable matching with globstars (`**`).
219
220#### globstar
221
222 * Type: `boolean`
223 * Default: `true`
224
225The [`noglobstar`](#noglobstar) option without double-negation. This option has a higher priority then `noglobstar`.
226
227#### noext
228
229 * Type: `boolean`
230 * Default: `false`
231
232Disable extglob support (patterns like `+(a|b)`), so that extglobs are regarded as literal characters.
233
234#### extension
235
236 * Type: `boolean`
237 * Default: `true`
238
239The [`noext`](#noext) option without double-negation. This option has a higher priority then `noext`.
240
241#### nocase
242
243 * Type: `boolean`
244 * Default: `false`
245
246Disable a case-insensitive regex for matching files.
247
248#### case
249
250 * Type: `boolean`
251 * Default: `true`
252
253The [`nocase`](#nocase) option without double-negation. This option has a higher priority then `nocase`.
254
255#### matchBase
256
257 * Type: `boolean`
258 * Default: `false`
259
260Allow 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`.
261
262#### transform
263
264 * Type: `Function`
265 * Default: `null`
266
267Allows you to transform a path or `fs.Stats` object before sending to the array.
268
269```js
270const fg = require('fast-glob');
271
272const entries1 = fg.sync(['**/*.scss']);
273const entries2 = fg.sync(['**/*.scss'], { transform: (entry) => '_' + entry });
274
275console.log(entries1); // ['a.scss', 'b.scss']
276console.log(entries2); // ['_a.scss', '_b.scss']
277```
278
279If you are using **TypeScript**, you probably want to specify your own type of the returned array.
280
281```ts
282import * as fg from 'fast-glob';
283
284interface IMyOwnEntry {
285 path: string;
286}
287
288const entries: IMyOwnEntry[] = fg.sync<IMyOwnEntry>(['*.md'], {
289 transform: (entry) => typeof entry === 'string' ? { path: entry } : { path: entry.path }
290 // Will throw compilation error for non-IMyOwnEntry types (boolean, for example)
291});
292```
293
294## How to exclude directory from reading?
295
296You can use a negative pattern like this: `!**/node_modules` or `!**/node_modules/**`. Also you can use `ignore` option. Just look at the example below.
297
298```
299first/
300├── file.md
301└── second
302 └── file.txt
303```
304
305If you don't want to read the `second` directory, you must write the following pattern: `!**/second` or `!**/second/**`.
306
307```js
308fg.sync(['**/*.md', '!**/second']); // ['first/file.txt']
309fg.sync(['**/*.md'], { ignore: '**/second/**' }); // ['first/file.txt']
310```
311
312> :warning: When you write `!**/second/**/*` it means that the directory will be **read**, but all the entries will not be included in the results.
313
314You have to understand that if you write the pattern to exclude directories, then the directory will not be read under any circumstances.
315
316## Compatible with `node-glob`?
317
318Not fully, because `fast-glob` does not implement all options of `node-glob`. See table below.
319
320| node-glob | fast-glob |
321| :----------: | :-------: |
322| `cwd` | [`cwd`](#cwd) |
323| `root` | – |
324| `dot` | [`dot`](#dot) |
325| `nomount` | – |
326| `mark` | [`markDirectories`](#markdirectories) |
327| `nosort` | – |
328| `nounique` | [`unique`](#unique) |
329| `nobrace` | [`nobrace`](#nobrace) or [`brace`](#brace) |
330| `noglobstar` | [`noglobstar`](#noglobstar) or [`globstar`](#globstar) |
331| `noext` | [`noext`](#noext) or [`extension`](#extension) |
332| `nocase` | [`nocase`](#nocase) or [`case`](#case) |
333| `matchBase` | [`matchbase`](#matchbase) |
334| `nodir` | [`onlyFiles`](#onlyfiles) |
335| `ignore` | [`ignore`](#ignore) |
336| `follow` | [`followSymlinkedDirectories`](#followsymlinkeddirectories) |
337| `realpath` | – |
338| `absolute` | [`absolute`](#absolute) |
339
340## Benchmarks
341
342**Tech specs:**
343
344Server: [Vultr Bare Metal](https://www.vultr.com/pricing/baremetal)
345
346 * Processor: E3-1270v6 (8 CPU)
347 * RAM: 32GB
348 * Disk: SSD
349
350You can see results [here](https://gist.github.com/mrmlnc/f06246b197f53c356895fa35355a367c) for latest release.
351
352## Related
353
354 * [readdir-enhanced](https://github.com/BigstickCarpet/readdir-enhanced) – Fast functional replacement for `fs.readdir()`.
355 * [globby](https://github.com/sindresorhus/globby) – User-friendly glob matching.
356 * [node-glob](https://github.com/isaacs/node-glob) – «Standard» glob functionality for Node.js
357 * [bash-glob](https://github.com/micromatch/bash-glob) – Bash-powered globbing for node.js.
358 * [glob-stream](https://github.com/gulpjs/glob-stream) – A Readable Stream interface over node-glob that used in the [gulpjs](https://github.com/gulpjs/gulp).
359
360## Changelog
361
362See the [Releases section of our GitHub project](https://github.com/mrmlnc/fast-glob/releases) for changelogs for each release version.
363
364## License
365
366This software is released under the terms of the MIT license.