node.jsglobfs-extra

copying files using `ncp` throws: no such file or directory, mkdir


I'm using ncp to copy files as following:

import ncp from "ncp";
import { promisify } from "util";

const ncpPromise = promisify(ncp);
const copyAssets = async (exportFolderName, includeSourceMaps) => {
  const assets = glob.sync("**/", { cwd: distPath });
  const options = { clobber: true, stopOnErr: true };
  if (!includeSourceMaps) {
    options.filter = (f) => {
      return !f.endsWith(".map");
    };
  }
  return Promise.all(
    assets.map((asset) => {
      return ncpPromise(
        path.join(distPath, asset),
        path.join(exportPath, exportFolderName, asset),
        options
      );
    })
  );
};

But this sometimes fails with the following error:

"ENOENT: no such file or directory, mkdir '/path/to/folder'"

How can I solve this ?


Solution

  • I guess you are trying to copy all files matching for the given glob, so you need to do:

    const assets = glob.sync("**/*.*", { cwd: distPath }); // note the *.*
    

    For example, your current glob in question will result into:

    [
      'folder1/',
      'folder2/',
    ]
    

    whereas the glob in this answer will result into (This is what you want):

    [
      'folder1/file1.txt',
      'folder1/file2.txt',
      'folder2/anotherfile.txt',
    ]
    

    An Alternative:

    Seems like ncp isn't being maintained. So, you can use fs-extra, it can copy file and directory as well:

    const glob = require("glob");
    const path = require("path");
    const fs = require("fs-extra");
    
    const copyAssets = async (exportFolderName, includeSourceMaps) => {
      const assets = glob.sync("**/*.*", { cwd: distPath });
    
      const options = { overwrite: true };
    
      if (!includeSourceMaps) {
        options.filter = (f) => {
          return !f.endsWith(".map");
        };
      }
    
      return Promise.all(
        assets.map((asset) => {
          return fs
            .copy(
              path.join(distPath, asset),
              path.join(exportPath, exportFolderName, asset),
              options
            )
            .catch((e) => console.log(e));
        })
      );
    };