Mastering the filesystem in Node.js
Node prides itself for having a minimal core. Where some languages ship bindings for the full POSIX API, Node tries to ship the minimum amount of bindings required to provide full functionality and exposes it through a sync, async and stream api.
This approach means that there are some convenience functions that ship in the OS that must be recreated in Node. This is a pragmatic guide to staple Node filesystem packages.
When interacting with the filesystem it’s important to point to the right file. As npm packages are bundled into other repositories it’s important to use dynamic links, rather than hardcoding relationships. There are two staple patterns to make sure packages reference the right files:
In Node the easiest way of asynchronously reading files is to use streams! Here’s an example:
Creating files isn’t that much harder, here’s a Node implementation of the shell cat command:
Removing files and directories is usually done with the shell rm -rf command. In Node this would be achieved using the rimraf package:
Creating directories is very similar to removing files using the mkdirp package:
Find files in the current directory with readdirp:
Find a file in the current directory’s parent directories with findup:
Note on robustness
Though I’ve never used it, I’ve heard good things about graceful-fs. It has retries, queues and other goodies built in. Give it a shot if you run into filesystem issues.
Note on pipes
When piping lots of streams together it’s important to handle error events. Rather than doing .on(‘error’, cb) on each individual stream it’s recommended to use pump to handle errors and properly close streams.
Shout out to Titus Wormer (@wooorm) for proof reading.
Originally published at github.com on September 20, 2015.