gulp (v4) の削除タスク 〜 特定のディレクトリ/ファイルを除外


ファイルやディレクトリの削除をしてくれるパッケージ del (npm) を使う。
del は rimraf に比べ以下の点が優れている。

  • 対象ファイルを柔軟に指定できる (複数、glob)
  • 保護機能
    • カレントディレクトリ以上の削除には、要 force オプション
    • Dry Run 機能 (実際には削除せず、対象ファイルを表示してくれる)
  • Promise API .then() で"成功なら続けて処理" ができる

サンプル

※ 【重要】試す場合は要バックアップ。意図せず重要なファイルを削除してしまう可能性がある。

以下のディレクトリ構成で、ルートフォルダ(project)から「dev ディレクトリ以外」のファイルを全削除したい場合

project/
 ├ dev/
 │  ├ gulpfile.babel.js
 │  ├ package.json
 │  ├ node_modules/
 │  ├ src/
 │  │  ├ style.scss
 │  │  ├ js/
 │  │  │  ├ main.js
 │  │  │  ├ sub.js 
 │  │  │  ├ vendor/
 ├ index.html 
 ├ style.css
 ├ js/
 │  ├ main.bundle.js
 │  ├ vendor.bundle.js
 ├ 

npx gulp clean で実行
(Babel で es6(ES2015) が動く環境にしているのが前提)

gulpfile.babel.js
import path from 'path';
import del from 'del';
import gulp from 'gulp';

/**
 * 対象ファイルのパス
 */
const rootdir = path.resolve(__dirname + '/..');
const paths = {
  del([
    rootdir + '/**',
    '!' + rootdir, // これがないと自身のディレクトリ自体が全削除されてしまう😱
    '!' + rootdir + '/dev', // これがないと dev 自体が全削除されてしまう
    '!' + rootdir + '/dev/**'
  ]);
};


/**
 * gulp の削除タスク
 */
export const clean = () => del(
  paths.del,
  {
    force: true, // カレントディレクトリ以上を対象にするなら必要
    dryRun: true // テスト(本番時はコメントアウト)
  }
).then(paths => {
  // eslint-disable-next-line no-console
  console.log('Files and folders that would be deleted:\n', paths.join('\n'));
});

glob パターン ** は、全ての子要素と親を対象とするので、除外しないと意図しないディレクトリが削除されてしまう。例えば、[rootdir, '!' + rootdir + '/dev/**/*'] だとルートディレクトリごと消えてしまう

参考記事