クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【gulp】我、破壊神となりてdelをもってファイルを削除すべし

メタ言語の続きです。前回gulp.tusk()をgulp4が推奨する関数の形に書き換えました。今回はファイルの削除!コンパイル後にファイルの削除やリネイムが反映されなかったため。delを使います。それではいきましょう!

【目次】

※参考:前回記事
【gulpfile.js】gulp.task()を関数化(←gulp4推奨)他、リファクタリング - クモのようにコツコツと

※参考:【メタ言語】HTMLテンプレートエンジン、AltCSS、AltJSのまとめ
qiita.com

前回のおさらい

gulp.tusk()を関数に書き換え。gulp4で推奨された形。

修正前

// sassコンパイル
gulp.task('sass', (done) => {
    gulp.src('./src/scss/**/*.scss')
        .pipe(sass({
                    outputStyle: 'expanded'
                })
            )
        .on("error", sass.logError)
        .pipe(gulp.dest('./dest/css'));
    done();
});

修正後

// sassコンパイル
const compileSass = (done) => {
    gulp.src(srcScssFiles)
        .pipe(sass({
                    outputStyle: 'expanded'
                })
            )
        .on('error', sass.logError)
        .pipe(gulp.dest(destCssDir));
    done();
};

returnを使う形だと動かない関数があったため、コールバック関数done()で統一した。

詳細は前回記事を参照

※参考:【gulpfile.js】gulp.task()を関数化(←gulp4推奨)他、リファクタリング - クモのようにコツコツと

ファイルのリネイムや削除がコンパイルに反映されない!

これは前々回の画像圧縮設定を作っている時に気づいた挙動なのだが、現状のコンパイル環境ではファイルのリネイムや削除がコンパイルに反映されない。

※参考:【gulp-imagemin】メタ言語コンパイル環境で画像圧縮も実行する - クモのようにコツコツと

例えばコンパイル前の「/src/img」フォルダの画像ファイルの「header_bg.jpg」 f:id:idr_zz:20201128113454j:plain

ファイル名を「header_bg_.jpg」に変えてみる。 f:id:idr_zz:20201128113456j:plain

コンパイル後の「/dest/img」フォルダを見ると「header_bg_.jpg」が書き出されている。 f:id:idr_zz:20201128113500j:plain
しかし元の「header_bg.jpg」も残ったまま。

次に「/src/img」フォルダの「header_bg_.jpg」のファイルを削除してみる。 f:id:idr_zz:20201128113503j:plain

しかし、「/dest/img」フォルダのファイルは変わらないまま。 f:id:idr_zz:20201128113500j:plain

このままだとリネイムや削除をした場合は「dest」フォルダの中で手作業でファイルを削除しなければならない。「dest」フォルダの中のファイルをいじるのはできれば避けたい。

delにて破壊神になる!

リネイムや削除もコンパイルに反映する方法を調べていると、このQAに出会った。

※参考:CSS - gulpでのファイル削除やリネームについて|teratail

創造の前には破壊が必要です。

その発想が思いつきませんでした。早速破壊神になり、破壊してみました!

つまり、毎回フォルダごと削除して、コピーしている

ぬおー、なるほど、そういうことか!フォルダごと削除しちゃってから再度コンパイルすれば、ファイルは削除できそうだ。自分もぜひなりたいぞ、その「破壊神」とやらに!!!

ファイルの削除は「del」というパッケージを使えばできそう。

※参考:del - npm

その他、参考にさせていただいた記事。

※参考記事:
gulp/delete-files-folder.md at master · gulpjs/gulp · GitHub
ファイルとフォルダの削除 | gulp 日本語リファレンス | js STUDIO
gulp - delを使用してファイルを削除する | gulp Tutorial
Gulp でファイル削除を監視して変更先のファイルも削除する - Corredor
[gulp4] gulpfileのつまずきアレコレ - Qiita

delをインストール、インポート

早速「del」をインストールする。こちらのコマンド

$ npm install del

package.jsonを確認。追加された!

  "dependencies": {
    "@types/node": "^14.14.7",
    "del": "^6.0.0", // 追加
    "typescript": "^4.0.5"
  }

gulpfile.jsにインポートdelをインポートする。

const del = require('del');

削除する関数を作成

全ファイル削除

変数destFiles/destフォルダの全ファイルのパスを追加する。

const destFiles = './dest/**/*';

新たにclean関数を作成

// destフォルダのファイル削除
const clean = (done) => {
    del([destFiles, '!' + destCssDir, '!' + destJsDir, '!' + destImtDir]);
    done();
};
  • 変数cleanの値は無名関数で引数はdone
  • del()関数を実行(引数は配列で削除するパスdestFilesを指定。ただし、destCssDirdestJsDirdestImtDirは除外)
  • done()を実行

以前作ったEJSのコンパイルの設定と同じで!を付ける除外設定になる。「css」「js」「img」フォルダは残したいので削除から除外した。

※参考:【HTML】EJSをGulpでコンパイルしてみる(SyntaxErrorでちょい苦戦) - クモのようにコツコツと

HTMLファイルを削除

次に各ファイルごとの削除設定のタスクを作る。

htmlClean関数を作成

// HTMLファイル削除
const htmlClean = (done) => {
    del([destHtmlFiles]);
    done();
};
  • 変数htmlCleanの値は無名関数で引数はdone
  • del()関数を実行(引数は配列で削除するパスdestHtmlFilesを指定)
  • done()を実行

これでHTMLファイルのみを全削除される。

画像ファイルを削除

次は画像ファイルの削除設定

imgClean関数を作る

// 画像ファイル削除
const imgClean = (done) => {
    del([destImgFiles]);
    done();
};
  • 変数imgCleanの値は無名関数で引数はdone
  • del()関数を実行(引数は配列で削除するパスdestImgFilesを指定)
  • done()を実行

これで画像ファイルのみを全削除される。

なお、CSSとJSについては1ファイルにバンドルする前提のため、ファイルの削除は生じない。

タスク化

先ほど作った関数をタスク化する

前回のタスク化のブロックに下記を追加

// タスク化
// (中略)
exports.clean = clean;
exports.htmlClean = htmlClean;
exports.imgClean = imgClean;

exports.hogeに過数名を紐づける

watchタスクにhtmlCleanとimgCleanを追加

変数watchFilesに画像とHTMLの削除設定を追加

// 監視ファイル
const watchFiles = (done) => {
    gulp.watch([srcEjsFiles, srcJsonFiles], gulp.series(htmlClean, compileEjs)); // 変更
    gulp.watch(destHtmlFiles, reloadBrowser);
    gulp.watch(srcScssFiles, compileSass);
    gulp.watch(destCssFiles, reloadBrowser);
    gulp.watch([srcTsFiles, srcJsonFiles], bundleWebpack);
    gulp.watch(destJSFiles, reloadBrowser);
    gulp.watch(srcImgFiles, gulp.series(imgClean, minifyImage)); // 変更
    gulp.watch(destImgFiles, reloadBrowser);
    done();
};
  • gulp.watch()srcEjsFilessrcJsonFilesのファイルを監視し、変更があったらgulp.series()htmlCleancompileEjsタスクを実行
  • gulp.watch()srcImgFilesのファイルを監視し、変更があったらgulp.series()imgCleanminifyImageタスクを実行

gulp.series()はこの下のdefault設定でも使っているように複数のタスクを直列で実行する。

HTMLとEJSのファイルに変更があったらhtmlCleanでHTMLファイルを削除しcompileEjsでEJSをHTMLにコンパイル。

画像ファイルに変更があったらimgCleanで画像ファイルを削除しminifyImageで画像圧縮を実行。

デフォルトのタスクにcleanを追加

exports.defaultを修正

// タスク実行
exports.default = gulp.series(
    clean, watchFiles, reloadFile, compileEjs, compileSass, bundleWebpack, minifyImage
);

gulp.series()で実行するタスクの一番最初にcleanを追加。

これでgulpを起動した時に最初に全ファイルを削除する。

変更内容(GitHub)
※参考:ファイルの削除設定を追加 · ryo-i/frontendMetaLanguage@64c315d · GitHub

動作確認

gulp起動

gulpを起動して動作を確認する。

$ npm start

HTMLファイルの変更

コンパイル前の「/src/ejs」には「index.ejs」と「other.ejs」がある。 f:id:idr_zz:20201128113510j:plain

コンパイル後の「/dest」直下には「index.html」と「other.html」がある。 f:id:idr_zz:20201128113506j:plain

「/src/ejs」の「other.ejs」を「other---.ejs」に変更すると f:id:idr_zz:20201128113513j:plain

おお!「/dest」直下の「other.html」が「other---.html」に変更された! f:id:idr_zz:20201128113516j:plain

次に「/src/ejs」の「other.ejs」を削除してみると f:id:idr_zz:20201128113518j:plain

「/dest」直下の「other.html」も削除された! f:id:idr_zz:20201128113521j:plain

画像ファイルの変更

圧縮前の「/src/img」に「header_bg.jpg」がある。 f:id:idr_zz:20201128122944j:plain

圧縮後の「/dest/img」に「header_bg.jpg」がある。 f:id:idr_zz:20201128122948j:plain

「/src/img」の「header_bg.jpg」を「header_bg---.jpg」に変更すると f:id:idr_zz:20201128122952j:plain

「/dest/img」の「header_bg.jpg」も「header_bg---.jpg」に変更された! f:id:idr_zz:20201128122955j:plain

次に「/src/img」の画像を削除すると f:id:idr_zz:20201128113524j:plain

「/dest/img」の画像も削除された! f:id:idr_zz:20201128113528j:plain

gulp起動で立ち上がっていたプレビュー画面も f:id:idr_zz:20201128113535j:plain

ヘッダーの背景画像のリンクが外れた! f:id:idr_zz:20201128113532j:plain


変更内容(GitHub)
※参考:ファイルの削除設定を追加 · ryo-i/frontendMetaLanguage@64c315d · GitHub

プレビュー画面(GitHub Pages)
※参考:メタ言語同時コンパイル(EJS、Sass(SCSS)、TypeScript)

最後に

ということでコンパイル時のファイルを追加のみでなく、削除、変名にも対応しました。

ファイルを個別に削除、変名するのではなくコンパイル前にファイルを全部削除してからまたファイル全体をコンパイルする、という方法で実現できるとは目には鱗。delを用いて破壊神になることができました。

それではまた!


※参考:【メタ言語】HTMLテンプレートエンジン、AltCSS、AltJSのまとめ
qiita.com