Create a snapshot of a directory for use with
memfs
I wanted something to help convert directories of test fixtures on-disk to a format usable by an in-memory filesystem (memfs).
To that end, the snapshot-fs
package ships a CLI, snapshot-fs
, which converts a directory tree to a DirectoryJSON
object (or JSON snapshot) for use with memfs
.
- The command-line options have changed; see Usage below.
snapshot-fs
can now re-create a directory on the filesystem from a JSON snapshot.loadSnapshot()
is nowreadSnapshot()
- Export functionality exposed via
exportSnapshot()
snapshot-fs
requires Node.js v22.13.0 or newer.
snapshot-fs
can be run via npx snapshot-fs
or installed globally via npm install -g snapshot-fs
. Or however else you want to consume it.
snapshot-fs
exports both CommonJS and ES modules.
snapshot-fs [dest]
Create JSON snapshot of directory
Commands:
snapshot-fs create [dest] Create JSON snapshot of directory
[default]
snapshot-fs export <snapshot> [dest] Export an existing snapshot to the files
ystem
Positionals:
dest Output .json file; if omitted, written to stdout [string]
Options:
--version Show version number [boolean]
--help Show help [boolean]
-b, --binary Output a memfs JSON snapshot instead of DirectoryJSON
[boolean]
-d, --dir Directory to read from
[string] [default: Current working directory]
-r, --json-root DirectoryJSON root [string] [default: "/"]
For more information, visit https://github.com/boneskull/snapshot-fs
When run without a subcommand, create
will be invoked.
If you aren't working with binary files and your directories are small, DirectoryJSON
is good enough.
snapshot-fs --dir /some/dir /path/to/output.json
or:
snapshot-fs create --dir /some/dir /path/to/output.json
In your code, you can use the resulting file:
import { memfs } from 'memfs';
import { readFile } from 'node:fs/promises';
/** @type {import('memfs').DirectoryJSON} */
const directoryJson = await readFile('/path/to/output.json', 'utf8').then(
JSON.parse,
);
const { vol } = memfs(directoryJson);
console.log(vol.toTree());
// ... do your thing
memfs's DirectoryJSON
format doesn't support binary files. If you need to support binary files—or you're interested in re-exporting back to the filesystem later—use the --binary
flag. This creates a JSON snapshot (for the curious, it's encoded as "Compact JSON") and must be consumed differently.
Note
The resulting JSON is for machines.
snapshot-fs create --binary --dir /some/dir /path/to/output.json
Here's an example of using the result:
import { readFile } from 'node:fs/promises';
import { fromJsonSnapshot } from 'memfs/lib/snapshot/index.js';
/**
* @import {SnapshotNode} from 'memfs/lib/snapshot/types.js';
* @import {JsonUint8Array} from 'memfs/lib/snapshot/index.js';
*/
const snapshotJson = /** @type {JsonUint8Array<SnapshotNode>} */ (
await readFile('/path/to/output.json') // read as a Buffer!
);
const { vol } = memfs();
// `fromJsonSnapshot` will populate the Volume at the root path /
// with the snapshot data
await fromJsonSnapshot(snapshot, { fs: vol.promises, path: '/' });
This allows you to re-create a directory on the filesystem from a snapshot. Handy!
snapshot-fs export <snapshot> [dest]
Export an existing snapshot to the filesystem
Positionals:
snapshot Path to snapshot .json file [string] [required]
dest Destination directory [string] [default: Current working directory]
Options:
--version Show version number [boolean]
--help Show help [boolean]
If you have a snapshot (either format) and you want to re-create snapshot on the filesystem, use the export
subcommand:
snapshot-fs export /path/to/snapshot.json /path/to/output
The destination directory will be created if it doesn't exist.
Careful with this one!
snapshot-fs
exports both ESM and CJS modules.
Some potentially-useful stuff exported from snapshot-fs
:
createSnapshot()
- Create a JSON snapshot from a real or virtual FScreateDirectoryJson()
- Create aDirectoryJSON
object from a real or virtual FS; warns if a binary file is detectedreadSnapshot()
- Read a snapshot from a file and load it into a real or virtual FSexportSnapshot()
- Alias forreadSnapshot()
defaulting to the real FSisCompactJson()
- Type guard to check if aUint8Array
is a Compact JSON snapshot
See the typings for more information.
Copyright 2024 Christopher Hiller. Licensed Apache-2.0