[Node.js] ディレクトリをコピーする方法
3 min read
概要
Node.jsのfsモジュールにはファイルのコピーをするためのcopyFile
が存在する。しかし、ディレクトリをコピーするためのcopyDirectory
のようなメソッドは存在しないため、必要があれば独自で作る必要がある。
fs-extraなどのようなライブラリには、この手の関数が存在しているため利用されることが多い。
コード
以下のコードでディレクトリをコピーできる。ただ、条件として素のNode.jsではなく、TypeScriptで記述しているため、node-ts
やesbuild
などのコンパイラを用いて実行する必要がある。
import { copyFile, mkdir, readdir } from 'node:fs/promises';
import path from 'node:path';
export const copyDir = async (src: string, dest: string) => {
try {
// コピー先ディレクトリが存在しない場合、作成する
await mkdir(dest, { recursive: true });
// コピー元のファイル・ディレクトリ一覧を取得する
const files = await readdir(src, { withFileTypes: true });
// 各エントリに対してコピー操作を実行する
for (const file of files) {
const srcPath = path.join(src, file.name);
const destPath = path.join(dest, file.name);
if (file.isDirectory()) {
// ディレクトリの場合、再帰的にコピーする
await copyDir(srcPath, destPath);
} else {
// ファイルの場合、単純にコピーする
await copyFile(srcPath, destPath);
}
}
} catch (error) {
console.error(`Error while copying directory: ${error}`);
}
};
createReadStream(src)
や createWriteStream(dst)
を利用してメモリ効率の良いコピーもできるが、今回は簡易的にcopyFile
を利用する。
解説
ディレクトリは単なるファイルではなく、ファイルを参照するためのデータ構造である。そのため、ディレクトリをコピーするためには、ディレクトリを作成し中のファイルを再帰的にコピーする必要がある。
コピー先ディレクトリの生成
最初に、コピー先のディレクトリを生成する。await mkdir(dest, { recursive: true });
コピー元の一覧取得
readdir
メソッドを用いて、コピー元のファイルおよびディレクトリの一覧を取得する。const files = await readdir(src, { withFileTypes: true });
ファイルおよびディレクトリのコピー
コピー元の一覧に基づき、ファイルとディレクトリをコピーする。ディレクトリの場合は、同じことを繰り返すため再帰的に処理を行う。if (file.isDirectory()) { await copyDir(srcPath, destPath); } else { await copyFile(srcPath, destPath); }