UNPKG

10.6 kBMarkdownView Raw
1Node.js: fs-extra
2=================
3
4`fs-extra` adds file system methods that aren't included in the native `fs` module and adds promise support to the `fs` methods. It also uses [`graceful-fs`](https://github.com/isaacs/node-graceful-fs) to prevent `EMFILE` errors. It should be a drop in replacement for `fs`.
5
6[![npm Package](https://img.shields.io/npm/v/fs-extra.svg)](https://www.npmjs.org/package/fs-extra)
7[![License](https://img.shields.io/npm/l/fs-extra.svg)](https://github.com/jprichardson/node-fs-extra/blob/master/LICENSE)
8[![build status](https://img.shields.io/github/actions/workflow/status/jprichardson/node-fs-extra/ci.yml?branch=master)](https://github.com/jprichardson/node-fs-extra/actions/workflows/ci.yml?query=branch%3Amaster)
9[![downloads per month](http://img.shields.io/npm/dm/fs-extra.svg)](https://www.npmjs.org/package/fs-extra)
10[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
11
12Why?
13----
14
15I got tired of including `mkdirp`, `rimraf`, and `ncp` in most of my projects.
16
17
18
19
20Installation
21------------
22
23 npm install fs-extra
24
25
26
27Usage
28-----
29
30### CommonJS
31
32`fs-extra` is a drop in replacement for native `fs`. All methods in `fs` are attached to `fs-extra`. All `fs` methods return promises if the callback isn't passed.
33
34You don't ever need to include the original `fs` module again:
35
36```js
37const fs = require('fs') // this is no longer necessary
38```
39
40you can now do this:
41
42```js
43const fs = require('fs-extra')
44```
45
46or if you prefer to make it clear that you're using `fs-extra` and not `fs`, you may want
47to name your `fs` variable `fse` like so:
48
49```js
50const fse = require('fs-extra')
51```
52
53you can also keep both, but it's redundant:
54
55```js
56const fs = require('fs')
57const fse = require('fs-extra')
58```
59
60### ESM
61
62There is also an `fs-extra/esm` import, that supports both default and named exports. However, note that `fs` methods are not included in `fs-extra/esm`; you still need to import `fs` and/or `fs/promises` seperately:
63
64```js
65import { readFileSync } from 'fs'
66import { readFile } from 'fs/promises'
67import { outputFile, outputFileSync } from 'fs-extra/esm'
68```
69
70Default exports are supported:
71
72```js
73import fs from 'fs'
74import fse from 'fs-extra/esm'
75// fse.readFileSync is not a function; must use fs.readFileSync
76```
77
78but you probably want to just use regular `fs-extra` instead of `fs-extra/esm` for default exports:
79
80```js
81import fs from 'fs-extra'
82// both fs and fs-extra methods are defined
83```
84
85Sync vs Async vs Async/Await
86-------------
87Most methods are async by default. All async methods will return a promise if the callback isn't passed.
88
89Sync methods on the other hand will throw if an error occurs.
90
91Also Async/Await will throw an error if one occurs.
92
93Example:
94
95```js
96const fs = require('fs-extra')
97
98// Async with promises:
99fs.copy('/tmp/myfile', '/tmp/mynewfile')
100 .then(() => console.log('success!'))
101 .catch(err => console.error(err))
102
103// Async with callbacks:
104fs.copy('/tmp/myfile', '/tmp/mynewfile', err => {
105 if (err) return console.error(err)
106 console.log('success!')
107})
108
109// Sync:
110try {
111 fs.copySync('/tmp/myfile', '/tmp/mynewfile')
112 console.log('success!')
113} catch (err) {
114 console.error(err)
115}
116
117// Async/Await:
118async function copyFiles () {
119 try {
120 await fs.copy('/tmp/myfile', '/tmp/mynewfile')
121 console.log('success!')
122 } catch (err) {
123 console.error(err)
124 }
125}
126
127copyFiles()
128```
129
130
131Methods
132-------
133
134### Async
135
136- [copy](docs/copy.md)
137- [emptyDir](docs/emptyDir.md)
138- [ensureFile](docs/ensureFile.md)
139- [ensureDir](docs/ensureDir.md)
140- [ensureLink](docs/ensureLink.md)
141- [ensureSymlink](docs/ensureSymlink.md)
142- [mkdirp](docs/ensureDir.md)
143- [mkdirs](docs/ensureDir.md)
144- [move](docs/move.md)
145- [outputFile](docs/outputFile.md)
146- [outputJson](docs/outputJson.md)
147- [pathExists](docs/pathExists.md)
148- [readJson](docs/readJson.md)
149- [remove](docs/remove.md)
150- [writeJson](docs/writeJson.md)
151
152### Sync
153
154- [copySync](docs/copy-sync.md)
155- [emptyDirSync](docs/emptyDir-sync.md)
156- [ensureFileSync](docs/ensureFile-sync.md)
157- [ensureDirSync](docs/ensureDir-sync.md)
158- [ensureLinkSync](docs/ensureLink-sync.md)
159- [ensureSymlinkSync](docs/ensureSymlink-sync.md)
160- [mkdirpSync](docs/ensureDir-sync.md)
161- [mkdirsSync](docs/ensureDir-sync.md)
162- [moveSync](docs/move-sync.md)
163- [outputFileSync](docs/outputFile-sync.md)
164- [outputJsonSync](docs/outputJson-sync.md)
165- [pathExistsSync](docs/pathExists-sync.md)
166- [readJsonSync](docs/readJson-sync.md)
167- [removeSync](docs/remove-sync.md)
168- [writeJsonSync](docs/writeJson-sync.md)
169
170
171**NOTE:** You can still use the native Node.js methods. They are promisified and copied over to `fs-extra`. See [notes on `fs.read()`, `fs.write()`, & `fs.writev()`](docs/fs-read-write-writev.md)
172
173### What happened to `walk()` and `walkSync()`?
174
175They were removed from `fs-extra` in v2.0.0. If you need the functionality, `walk` and `walkSync` are available as separate packages, [`klaw`](https://github.com/jprichardson/node-klaw) and [`klaw-sync`](https://github.com/manidlou/node-klaw-sync).
176
177
178Third Party
179-----------
180
181### CLI
182
183[fse-cli](https://www.npmjs.com/package/@atao60/fse-cli) allows you to run `fs-extra` from a console or from [npm](https://www.npmjs.com) scripts.
184
185### TypeScript
186
187If you like TypeScript, you can use `fs-extra` with it: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/fs-extra
188
189
190### File / Directory Watching
191
192If you want to watch for changes to files or directories, then you should use [chokidar](https://github.com/paulmillr/chokidar).
193
194### Obtain Filesystem (Devices, Partitions) Information
195
196[fs-filesystem](https://github.com/arthurintelligence/node-fs-filesystem) allows you to read the state of the filesystem of the host on which it is run. It returns information about both the devices and the partitions (volumes) of the system.
197
198### Misc.
199
200- [fs-extra-debug](https://github.com/jdxcode/fs-extra-debug) - Send your fs-extra calls to [debug](https://npmjs.org/package/debug).
201- [mfs](https://github.com/cadorn/mfs) - Monitor your fs-extra calls.
202
203
204
205Hacking on fs-extra
206-------------------
207
208Wanna hack on `fs-extra`? Great! Your help is needed! [fs-extra is one of the most depended upon Node.js packages](http://nodei.co/npm/fs-extra.png?downloads=true&downloadRank=true&stars=true). This project
209uses [JavaScript Standard Style](https://github.com/feross/standard) - if the name or style choices bother you,
210you're gonna have to get over it :) If `standard` is good enough for `npm`, it's good enough for `fs-extra`.
211
212[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)
213
214What's needed?
215- First, take a look at existing issues. Those are probably going to be where the priority lies.
216- More tests for edge cases. Specifically on different platforms. There can never be enough tests.
217- Improve test coverage.
218
219Note: If you make any big changes, **you should definitely file an issue for discussion first.**
220
221### Running the Test Suite
222
223fs-extra contains hundreds of tests.
224
225- `npm run lint`: runs the linter ([standard](http://standardjs.com/))
226- `npm run unit`: runs the unit tests
227- `npm run unit-esm`: runs tests for `fs-extra/esm` exports
228- `npm test`: runs the linter and all tests
229
230When running unit tests, set the environment variable `CROSS_DEVICE_PATH` to the absolute path of an empty directory on another device (like a thumb drive) to enable cross-device move tests.
231
232
233### Windows
234
235If you run the tests on the Windows and receive a lot of symbolic link `EPERM` permission errors, it's
236because on Windows you need elevated privilege to create symbolic links. You can add this to your Windows's
237account by following the instructions here: http://superuser.com/questions/104845/permission-to-make-symbolic-links-in-windows-7
238However, I didn't have much luck doing this.
239
240Since I develop on Mac OS X, I use VMWare Fusion for Windows testing. I create a shared folder that I map to a drive on Windows.
241I open the `Node.js command prompt` and run as `Administrator`. I then map the network drive running the following command:
242
243 net use z: "\\vmware-host\Shared Folders"
244
245I can then navigate to my `fs-extra` directory and run the tests.
246
247
248Naming
249------
250
251I put a lot of thought into the naming of these functions. Inspired by @coolaj86's request. So he deserves much of the credit for raising the issue. See discussion(s) here:
252
253* https://github.com/jprichardson/node-fs-extra/issues/2
254* https://github.com/flatiron/utile/issues/11
255* https://github.com/ryanmcgrath/wrench-js/issues/29
256* https://github.com/substack/node-mkdirp/issues/17
257
258First, I believe that in as many cases as possible, the [Node.js naming schemes](http://nodejs.org/api/fs.html) should be chosen. However, there are problems with the Node.js own naming schemes.
259
260For example, `fs.readFile()` and `fs.readdir()`: the **F** is capitalized in *File* and the **d** is not capitalized in *dir*. Perhaps a bit pedantic, but they should still be consistent. Also, Node.js has chosen a lot of POSIX naming schemes, which I believe is great. See: `fs.mkdir()`, `fs.rmdir()`, `fs.chown()`, etc.
261
262We have a dilemma though. How do you consistently name methods that perform the following POSIX commands: `cp`, `cp -r`, `mkdir -p`, and `rm -rf`?
263
264My perspective: when in doubt, err on the side of simplicity. A directory is just a hierarchical grouping of directories and files. Consider that for a moment. So when you want to copy it or remove it, in most cases you'll want to copy or remove all of its contents. When you want to create a directory, if the directory that it's suppose to be contained in does not exist, then in most cases you'll want to create that too.
265
266So, if you want to remove a file or a directory regardless of whether it has contents, just call `fs.remove(path)`. If you want to copy a file or a directory whether it has contents, just call `fs.copy(source, destination)`. If you want to create a directory regardless of whether its parent directories exist, just call `fs.mkdirs(path)` or `fs.mkdirp(path)`.
267
268
269Credit
270------
271
272`fs-extra` wouldn't be possible without using the modules from the following authors:
273
274- [Isaac Shlueter](https://github.com/isaacs)
275- [Charlie McConnel](https://github.com/avianflu)
276- [James Halliday](https://github.com/substack)
277- [Andrew Kelley](https://github.com/andrewrk)
278
279
280
281
282License
283-------
284
285Licensed under MIT
286
287Copyright (c) 2011-2017 [JP Richardson](https://github.com/jprichardson)
288
289[1]: http://nodejs.org/docs/latest/api/fs.html
290
291
292[jsonfile]: https://github.com/jprichardson/node-jsonfile