Node.js: fs-extra

`fs-extra` adds file system methods that aren't included in the native `fs` module and adds promise support to the `fs` methods. It should be a drop in replacement for `fs`.

# Why?

I got tired of including `mkdirp`, `rimraf`, and `ncp` in most of my projects.

# Installation

    npm install --save fs-extra

# Usage

`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.

You don't ever need to include the original `fs` module again:

const fs = require('fs') // this is no longer necessary

you can now do this:

const fs = require('fs-extra')

or if you prefer to make it clear that you're using `fs-extra` and not `fs`, you may want to name your `fs` variable `fse` like so:

const fse = require('fs-extra')

you can also keep both, but it's redundant:

const fs = require('fs')
const fse = require('fs-extra')

# Sync vs Async

Most methods are async by default. All async methods will return a promise if the callback isn't passed.

Sync methods on the other hand will throw if an error occurs.

Example:

const fs = require('fs-extra')
// Async with promises:
fs.copy('/tmp/myfile', '/tmp/mynewfile')
.then(() => console.log('success!'))
.catch(err => console.error(err))
// Async with callbacks:
fs.copy('/tmp/myfile', '/tmp/mynewfile', err => {
if (err) return console.error(err)
console.log('success!')
})
// Sync:
try {
fs.copySync('/tmp/myfile', '/tmp/mynewfile')
console.log('success!')
} catch (err) {
console.error(err)
}

# Methods

## Async

- copy
- emptyDir
- ensureFile
- ensureDir
- ensureLink
- ensureSymlink
- mkdirs
- move
- outputFile
- outputJson
- pathExists
- readJson
- remove
- writeJson

## Sync

- copySync
- emptyDirSync
- ensureFileSync
- ensureDirSync
- ensureLinkSync
- ensureSymlinkSync
- mkdirsSync
- moveSync
- outputFileSync
- outputJsonSync
- pathExistsSync
- readJsonSync
- removeSync
- writeJsonSync

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()`

## What happened to <tt>walk()</tt> and <tt>walkSync()</tt>?

They were removed from `fs-extra` in v2.0.0. If you need the functionality, `walk` and `walkSync` are available as separate packages, `klaw` and `klaw-sync`.

# Third Party

## TypeScript

If you like TypeScript, you can use `fs-extra` with it: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/fs-extra

## File / Directory Watching

If you want to watch for changes to files or directories, then you should use chokidar.

## Misc.

- mfs - Monitor your fs-extra calls.

# Hacking on fs-extra

Wanna hack on `fs-extra`? Great! Your help is needed! fs-extra is one of the most depended upon Node.js packages. This project uses JavaScript Standard Style - if the name or style choices bother you, you're gonna have to get over it :) If `standard` is good enough for `npm`, it's good enough for `fs-extra`.

What's needed?

- First, take a look at existing issues. Those are probably going to be where the priority lies.
- More tests for edge cases. Specifically on different platforms. There can never be enough tests.
- Improve test coverage. See coveralls output for more info.

Note: If you make any big changes, you should definitely file an issue for discussion first.

## Running the Test Suite

fs-extra contains hundreds of tests.

- `npm run lint`: runs the linter (standard)
- `npm run unit`: runs the unit tests
- `npm test`: runs both the linter and the tests

## Windows

If you run the tests on the Windows and receive a lot of symbolic link `EPERM` permission errors, it's because on Windows you need elevated privilege to create symbolic links. You can add this to your Windows's account by following the instructions here: http://superuser.com/questions/104845/permission-to-make-symbolic-links-in-windows-7 However, I didn't have much luck doing this.

Since 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. I open the `Node.js command prompt` and run as `Administrator`. I then map the network drive running the following command:

    net use z: "\\vmware-host\Shared Folders"

I can then navigate to my `fs-extra` directory and run the tests.

# Naming

I 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:

- https://github.com/jprichardson/node-fs-extra/issues/2
- https://github.com/flatiron/utile/issues/11
- https://github.com/ryanmcgrath/wrench-js/issues/29
- https://github.com/substack/node-mkdirp/issues/17

First, I believe that in as many cases as possible, the Node.js naming schemes should be chosen. However, there are problems with the Node.js own naming schemes.

For 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.

We have a dilemma though. How do you consistently name methods that perform the following POSIX commands: `cp`, `cp -r`, `mkdir -p`, and `rm -rf`?

My 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.

So, 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)`.

# Credit

`fs-extra` wouldn't be possible without using the modules from the following authors:

- Isaac Shlueter
- Charlie McConnel
- James Halliday
- Andrew Kelley

# License

Licensed under MIT

Copyright (c) 2011-2017 JP Richardson