[6a3a178] | 1 | # readdirp [![Weekly downloads](https://img.shields.io/npm/dw/readdirp.svg)](https://github.com/paulmillr/readdirp)
|
---|
| 2 |
|
---|
| 3 | Recursive version of [fs.readdir](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback). Exposes a **stream API** and a **promise API**.
|
---|
| 4 |
|
---|
| 5 |
|
---|
| 6 | ```sh
|
---|
| 7 | npm install readdirp
|
---|
| 8 | ```
|
---|
| 9 |
|
---|
| 10 | ```javascript
|
---|
| 11 | const readdirp = require('readdirp');
|
---|
| 12 |
|
---|
| 13 | // Use streams to achieve small RAM & CPU footprint.
|
---|
| 14 | // 1) Streams example with for-await.
|
---|
| 15 | for await (const entry of readdirp('.')) {
|
---|
| 16 | const {path} = entry;
|
---|
| 17 | console.log(`${JSON.stringify({path})}`);
|
---|
| 18 | }
|
---|
| 19 |
|
---|
| 20 | // 2) Streams example, non for-await.
|
---|
| 21 | // Print out all JS files along with their size within the current folder & subfolders.
|
---|
| 22 | readdirp('.', {fileFilter: '*.js', alwaysStat: true})
|
---|
| 23 | .on('data', (entry) => {
|
---|
| 24 | const {path, stats: {size}} = entry;
|
---|
| 25 | console.log(`${JSON.stringify({path, size})}`);
|
---|
| 26 | })
|
---|
| 27 | // Optionally call stream.destroy() in `warn()` in order to abort and cause 'close' to be emitted
|
---|
| 28 | .on('warn', error => console.error('non-fatal error', error))
|
---|
| 29 | .on('error', error => console.error('fatal error', error))
|
---|
| 30 | .on('end', () => console.log('done'));
|
---|
| 31 |
|
---|
| 32 | // 3) Promise example. More RAM and CPU than streams / for-await.
|
---|
| 33 | const files = await readdirp.promise('.');
|
---|
| 34 | console.log(files.map(file => file.path));
|
---|
| 35 |
|
---|
| 36 | // Other options.
|
---|
| 37 | readdirp('test', {
|
---|
| 38 | fileFilter: '*.js',
|
---|
| 39 | directoryFilter: ['!.git', '!*modules']
|
---|
| 40 | // directoryFilter: (di) => di.basename.length === 9
|
---|
| 41 | type: 'files_directories',
|
---|
| 42 | depth: 1
|
---|
| 43 | });
|
---|
| 44 | ```
|
---|
| 45 |
|
---|
| 46 | For more examples, check out `examples` directory.
|
---|
| 47 |
|
---|
| 48 | ## API
|
---|
| 49 |
|
---|
| 50 | `const stream = readdirp(root[, options])` — **Stream API**
|
---|
| 51 |
|
---|
| 52 | - Reads given root recursively and returns a `stream` of [entry infos](#entryinfo)
|
---|
| 53 | - Optionally can be used like `for await (const entry of stream)` with node.js 10+ (`asyncIterator`).
|
---|
| 54 | - `on('data', (entry) => {})` [entry info](#entryinfo) for every file / dir.
|
---|
| 55 | - `on('warn', (error) => {})` non-fatal `Error` that prevents a file / dir from being processed. Example: inaccessible to the user.
|
---|
| 56 | - `on('error', (error) => {})` fatal `Error` which also ends the stream. Example: illegal options where passed.
|
---|
| 57 | - `on('end')` — we are done. Called when all entries were found and no more will be emitted.
|
---|
| 58 | - `on('close')` — stream is destroyed via `stream.destroy()`.
|
---|
| 59 | Could be useful if you want to manually abort even on a non fatal error.
|
---|
| 60 | At that point the stream is no longer `readable` and no more entries, warning or errors are emitted
|
---|
| 61 | - To learn more about streams, consult the very detailed [nodejs streams documentation](https://nodejs.org/api/stream.html)
|
---|
| 62 | or the [stream-handbook](https://github.com/substack/stream-handbook)
|
---|
| 63 |
|
---|
| 64 | `const entries = await readdirp.promise(root[, options])` — **Promise API**. Returns a list of [entry infos](#entryinfo).
|
---|
| 65 |
|
---|
| 66 | First argument is awalys `root`, path in which to start reading and recursing into subdirectories.
|
---|
| 67 |
|
---|
| 68 | ### options
|
---|
| 69 |
|
---|
| 70 | - `fileFilter: ["*.js"]`: filter to include or exclude files. A `Function`, Glob string or Array of glob strings.
|
---|
| 71 | - **Function**: a function that takes an entry info as a parameter and returns true to include or false to exclude the entry
|
---|
| 72 | - **Glob string**: a string (e.g., `*.js`) which is matched using [picomatch](https://github.com/micromatch/picomatch), so go there for more
|
---|
| 73 | information. Globstars (`**`) are not supported since specifying a recursive pattern for an already recursive function doesn't make sense. Negated globs (as explained in the minimatch documentation) are allowed, e.g., `!*.txt` matches everything but text files.
|
---|
| 74 | - **Array of glob strings**: either need to be all inclusive or all exclusive (negated) patterns otherwise an error is thrown.
|
---|
| 75 | `['*.json', '*.js']` includes all JavaScript and Json files.
|
---|
| 76 | `['!.git', '!node_modules']` includes all directories except the '.git' and 'node_modules'.
|
---|
| 77 | - Directories that do not pass a filter will not be recursed into.
|
---|
| 78 | - `directoryFilter: ['!.git']`: filter to include/exclude directories found and to recurse into. Directories that do not pass a filter will not be recursed into.
|
---|
| 79 | - `depth: 5`: depth at which to stop recursing even if more subdirectories are found
|
---|
| 80 | - `type: 'files'`: determines if data events on the stream should be emitted for `'files'` (default), `'directories'`, `'files_directories'`, or `'all'`. Setting to `'all'` will also include entries for other types of file descriptors like character devices, unix sockets and named pipes.
|
---|
| 81 | - `alwaysStat: false`: always return `stats` property for every file. Default is `false`, readdirp will return `Dirent` entries. Setting it to `true` can double readdir execution time - use it only when you need file `size`, `mtime` etc. Cannot be enabled on node <10.10.0.
|
---|
| 82 | - `lstat: false`: include symlink entries in the stream along with files. When `true`, `fs.lstat` would be used instead of `fs.stat`
|
---|
| 83 |
|
---|
| 84 | ### `EntryInfo`
|
---|
| 85 |
|
---|
| 86 | Has the following properties:
|
---|
| 87 |
|
---|
| 88 | - `path: 'assets/javascripts/react.js'`: path to the file/directory (relative to given root)
|
---|
| 89 | - `fullPath: '/Users/dev/projects/app/assets/javascripts/react.js'`: full path to the file/directory found
|
---|
| 90 | - `basename: 'react.js'`: name of the file/directory
|
---|
| 91 | - `dirent: fs.Dirent`: built-in [dir entry object](https://nodejs.org/api/fs.html#fs_class_fs_dirent) - only with `alwaysStat: false`
|
---|
| 92 | - `stats: fs.Stats`: built in [stat object](https://nodejs.org/api/fs.html#fs_class_fs_stats) - only with `alwaysStat: true`
|
---|
| 93 |
|
---|
| 94 | ## Changelog
|
---|
| 95 |
|
---|
| 96 | - 3.5 (Oct 13, 2020) disallows recursive directory-based symlinks.
|
---|
| 97 | Before, it could have entered infinite loop.
|
---|
| 98 | - 3.4 (Mar 19, 2020) adds support for directory-based symlinks.
|
---|
| 99 | - 3.3 (Dec 6, 2019) stabilizes RAM consumption and enables perf management with `highWaterMark` option. Fixes race conditions related to `for-await` looping.
|
---|
| 100 | - 3.2 (Oct 14, 2019) improves performance by 250% and makes streams implementation more idiomatic.
|
---|
| 101 | - 3.1 (Jul 7, 2019) brings `bigint` support to `stat` output on Windows. This is backwards-incompatible for some cases. Be careful. It you use it incorrectly, you'll see "TypeError: Cannot mix BigInt and other types, use explicit conversions".
|
---|
| 102 | - 3.0 brings huge performance improvements and stream backpressure support.
|
---|
| 103 | - Upgrading 2.x to 3.x:
|
---|
| 104 | - Signature changed from `readdirp(options)` to `readdirp(root, options)`
|
---|
| 105 | - Replaced callback API with promise API.
|
---|
| 106 | - Renamed `entryType` option to `type`
|
---|
| 107 | - Renamed `entryType: 'both'` to `'files_directories'`
|
---|
| 108 | - `EntryInfo`
|
---|
| 109 | - Renamed `stat` to `stats`
|
---|
| 110 | - Emitted only when `alwaysStat: true`
|
---|
| 111 | - `dirent` is emitted instead of `stats` by default with `alwaysStat: false`
|
---|
| 112 | - Renamed `name` to `basename`
|
---|
| 113 | - Removed `parentDir` and `fullParentDir` properties
|
---|
| 114 | - Supported node.js versions:
|
---|
| 115 | - 3.x: node 8+
|
---|
| 116 | - 2.x: node 0.6+
|
---|
| 117 |
|
---|
| 118 | ## License
|
---|
| 119 |
|
---|
| 120 | Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (<https://paulmillr.com>)
|
---|
| 121 |
|
---|
| 122 | MIT License, see [LICENSE](LICENSE) file.
|
---|