在我的节点应用程序中,我需要删除一个目录,其中有一些文件,但fs。Rmdir只适用于空目录。我该怎么做呢?


当前回答

2020的答案

如果你想在npm脚本中完成它,如果你使用npx命令,你不需要预先安装任何第三方包

例如,如果你想在运行npm run clean时删除dist和.cache文件夹,那么只需将此命令添加到package.json中

{
  "scripts": {
    "clean": "npx rimraf dist .cache"
  }
}

它适用于任何操作系统

其他回答

另一种替代方法是使用fs-promise模块,该模块提供fs-extra模块的承诺版本

你可以这样写:

const { remove, mkdirp, writeFile, readFile } = require('fs-promise')
const { join, dirname } = require('path')

async function createAndRemove() {
  const content = 'Hello World!'
  const root = join(__dirname, 'foo')
  const file = join(root, 'bar', 'baz', 'hello.txt')

  await mkdirp(dirname(file))
  await writeFile(file, content)
  console.log(await readFile(file, 'utf-8'))
  await remove(join(__dirname, 'foo'))
}

createAndRemove().catch(console.error)

注意:async/await需要最新的nodejs版本(7.6+)

如果你正在使用的节点8+想要异步,不想要外部依赖,这里是async/await版本:

const path = require('path');
const fs = require('fs');
const util = require('util');

const readdir = util.promisify(fs.readdir);
const lstat = util.promisify(fs.lstat);
const unlink = util.promisify(fs.unlink);
const rmdir = util.promisify(fs.rmdir);

const removeDir = async (dir) => {
    try {
        const files = await readdir(dir);
        await Promise.all(files.map(async (file) => {
            try {
                const p = path.join(dir, file);
                const stat = await lstat(p);
                if (stat.isDirectory()) {
                    await removeDir(p);
                } else {
                    await unlink(p);
                    console.log(`Removed file ${p}`);
                }
            } catch (err) {
                console.error(err);
            }
        }))
        await rmdir(dir);
        console.log(`Removed dir ${dir}`);
    } catch (err) {
      console.error(err);
    }
}

[编辑:使用node.js v15.5.0]

刚刚尝试使用这里发布的一些解决方案后,我遇到了以下弃用警告:

(node:13202) [DEP0147] DeprecationWarning:在未来的版本 node . js, fs。Rmdir (path, {recursive: true})将抛出 不存在或者是一个文件。使用fs。Rm (path, {recursive: true, force: true }),而不是

fs。Rm (path,{递归:true, force: true});与fs一起工作很好。rmSync(path,{递归:true, force: true});如果你想使用阻塞版本。

同步文件夹删除文件或仅一个文件。 我不是一个很好的给予者,也不是一个贡献者,但我找不到一个很好的解决这个问题的方法,我必须找到我的方法……所以我希望你会喜欢它:) 适用于任何数量的嵌套目录和子目录。注意递归函数时'this'的作用域,您的实现可能不同。在我的例子中,这个函数保留在另一个函数的返回中这就是为什么我用这个来调用它。

    const fs = require('fs');

    deleteFileOrDir(path, pathTemp = false){
            if (fs.existsSync(path)) {
                if (fs.lstatSync(path).isDirectory()) {
                    var files = fs.readdirSync(path);
                    if (!files.length) return fs.rmdirSync(path);
                    for (var file in files) {
                        var currentPath = path + "/" + files[file];
                        if (!fs.existsSync(currentPath)) continue;
                        if (fs.lstatSync(currentPath).isFile()) {
                            fs.unlinkSync(currentPath);
                            continue;
                        }
                        if (fs.lstatSync(currentPath).isDirectory() && !fs.readdirSync(currentPath).length) {
                            fs.rmdirSync(currentPath);
                        } else {
                            this.deleteFileOrDir(currentPath, path);
                        }
                    }
                    this.deleteFileOrDir(path);
                } else {
                    fs.unlinkSync(path);
                }
            }
            if (pathTemp) this.deleteFileOrDir(pathTemp);
        }

同步删除文件夹

    const fs = require('fs');
    const Path = require('path');

    const deleteFolderRecursive = function (directoryPath) {
    if (fs.existsSync(directoryPath)) {
        fs.readdirSync(directoryPath).forEach((file, index) => {
          const curPath = path.join(directoryPath, file);
          if (fs.lstatSync(curPath).isDirectory()) {
           // recurse
            deleteFolderRecursive(curPath);
          } else {
            // delete file
            fs.unlinkSync(curPath);
          }
        });
        fs.rmdirSync(directoryPath);
      }
    };