The problem#
The straightforward OPFS API for deleting a directory
await parentDir.removeEntry(name, {recursive: true});
doesn't work if the directory contains too many (several hundred) levels of nested directories. The sensible workaround is never create such a directory structure and wipe the OPFS storage entirely if you ever do by accident, but as discussed previously, I did get in that situation due to a bug and wrote some helpers to deal with it.
The solution#
For any reasonable real-world case, what you actually want is probably
removeEntry()
:
await parentDir.removeEntry(name, {recursive: true});
or to delete everything from the root directory:
const root = await navigator.storage.getDirectory();
for await (const handle of root.values()) {
await root.removeEntry(handle.name, {recursive: true});
}
or possibly to simply use your browser's settings to delete all site data, which should include OPFS data.
In case you do still want to delete a directory in OPFS without worrying about how deeply nested the directory structure is, you can use
async function removeDirectoryFast(dir) {
const toDelete = [];
let i = 0;
let maxDepth = 0;
for await (const fileHandle
of getFilesNonRecursively(dir)) {
maxDepth = Math.max(maxDepth, fileHandle.depth);
toDelete.push(fileHandle);
}
async function deleteAtDepth(depth) {
for (const f of toDelete) {
if (f.depth === depth) {
await f.parentDir.removeEntry(f.name,
{recursive: true});
}
}
}
const increment = 500; // Works empirically in Firefox.
for (let depth = maxDepth; depth > 1; depth -= increment) {
await deleteAtDepth(depth);
}
await deleteAtDepth(1);
}
This depends on the getFilesNonRecursively()
helper from
my previous blog post.