Copy folder recursively in Node.js

前端 未结 25 1812
隐瞒了意图╮
隐瞒了意图╮ 2020-12-04 07:44

Is there an easier way to copy a folder and all its content without manually doing a sequence of fs.readir, fs.readfile, fs.writefile

相关标签:
25条回答
  • 2020-12-04 08:30

    Since I'm just building a simple Node.js script, I didn't want the users of the script to need to import a bunch of external modules and dependencies, so I put on my thinking cap and did a search for running commands from the Bash shell.

    This Node.js code snippet recursively copies a folder called node-webkit.app to a folder called build:

    child = exec("cp -r node-webkit.app build", function(error, stdout, stderr) {
        sys.print("stdout: " + stdout);
        sys.print("stderr: " + stderr);
        if(error !== null) {
            console.log("exec error: " + error);
        } else {
    
        }
    });
    

    Thanks to Lance Pollard at dzone for getting me started.

    The above snippet is limited to Unix-based platforms, like macOS and Linux, but a similar technique may work for Windows.

    0 讨论(0)
  • 2020-12-04 08:31

    For a Linux/Unix OS, you can use the shell syntax

    const shell = require('child_process').execSync;
    
    const src = `/path/src`;
    const dist = `/path/dist`;
    
    shell(`mkdir -p ${dist}`);
    shell(`cp -r ${src}/* ${dist}`);
    

    That's it!

    0 讨论(0)
  • 2020-12-04 08:32

    There are some modules that support copying folders with their content. The most popular would be wrench.js:

    // Deep-copy an existing directory
    wrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end_up');
    

    An alternative would be node-fs-extra:

    fs.copy('/tmp/mydir', '/tmp/mynewdir', function (err) {
      if (err) {
        console.error(err);
      } else {
        console.log("success!");
      }
    }); // Copies directory, even if it has subdirectories or files
    
    0 讨论(0)
  • 2020-12-04 08:32

    This is how I did it:

    let fs = require('fs');
    let path = require('path');
    

    Then:

    let filePath = // Your file path
    
    let fileList = []
        var walkSync = function(filePath, filelist)
        {
            let files = fs.readdirSync(filePath);
            filelist = filelist || [];
            files.forEach(function(file)
            {
                if (fs.statSync(path.join(filePath, file)).isDirectory())
                {
                    filelist = walkSync(path.join(filePath, file), filelist);
                }
                else
                {
                    filelist.push(path.join(filePath, file));
                }
            });
    
            // Ignore hidden files
            filelist = filelist.filter(item => !(/(^|\/)\.[^\/\.]/g).test(item));
    
            return filelist;
        };
    

    Then call the method:

    This.walkSync(filePath, fileList)
    
    0 讨论(0)
  • 2020-12-04 08:33

    The one with symbolic link support + doesn't throw if the destination directory already exists.

    function copyFolderSync(from, to) {
      try {
        fs.mkdirSync(to);
      } catch(e) {}
    
      fs.readdirSync(from).forEach((element) => {
        const stat = fs.lstatSync(path.join(from, element));
        if (stat.isFile()) {
          fs.copyFileSync(path.join(from, element), path.join(to, element));
        } else if (stat.isSymbolicLink()) {
          fs.symlinkSync(fs.readlinkSync(path.join(from, element)), path.join(to, element));
        } else if (stat.isDirectory()) {
          copyFolderSync(path.join(from, element), path.join(to, element));
        }
      });
    }
    
    0 讨论(0)
  • 2020-12-04 08:33

    If you are on Linux, and performance is not an issue, you may use the exec function from child_process module, to execute a Bash command:

    const { exec } = require('child_process');
    exec('cp -r source dest', (error, stdout, stderr) => {...});
    

    In some cases, I found this solution cleaner than downloading an entire module or even using the fs module.

    0 讨论(0)
提交回复
热议问题