今更だけどまぁまぁ便利なのでgulp4を使う
今更だけどまぁまぁ便利なのでgulp4を使う
はい。
今更gulpって、、、って感じもあるし、webpackだのparcelだの、いやいや、そもそも最近はcliが充実してるので、設定ファイル自体書かないんだよってことがあるのは知ってるけど、gulp4結構便利だったので書いておく。
ちなみに今普通にgulp落としてきたら4以降が落ちてくるけど、3.9.1との明確な差別化のためにこの記事ではgulp4と呼びます。
モチベーション
gulpが便利なときがある
業務でプラグインみたいなやつ書いてて、webpackだけだと結構だるかった。
要件的には以下。
- htmlとかcssとか扱いたいファイルが複数ある
- ただコピーしたいのがちょいちょいある
- 上書きしたいファイルが有る
- develop用に生成されたファイルをちょくちょく確認したい
特に【上書きしたいファイルが有る】はwebpackだと面倒そうな気配が結構あったので、それが決め手だった。
個人的には未だにウェブサイト作るなら、正直gulpは必須だと思う。
npm scriptsで頑張ってもいいけど、gulpの手軽さには代え難いし、特にウェブサイトの制作だと最終的にWordPressのテーマにしちゃうことも多いと思うし、そういう場合だとNuxtとかは向かなそうな印象ある。
◾️ gulp@3.9.1に引きずられた記事が多い
gulpは@3.9.1の時代が長かったので、巷にはその時代の書き方は死ぬ程転がってる。
もちろんgulp4の書き方も山のように転がってるけど、案外3.9.1を引きずった書き方ばっかだったので、そうじゃない書き方の紹介があってもいいだろうと思った。
個人的には4系の書き方のほうが断然好き。gulp書いてる感でなくjs書いてるなーって感じがするから。
gulpfile.js
まぁ、公式を読めって話だけど、往々にして人間は公式でなく日本語で書かれた記事を先にあたるので、こっちでも書いていく。
大雑把に何が違うかというと、大きいところではseries
とparallel
が入った。
今まで直列処理するのにrun-sequence
が必要だったけど、series
が代替できるようになった。
並列処理の場合はその名の通りparallel
を使う。
あとはmodule.exports
にタスクをぶら下げる事になったところも大きな変更点だと思う。
今までgulp.task()
で文字列と処理を渡してたけど、その書き方は非推奨になった。今でもそのAPIは使用可能なこともあって、この書き方を紹介した記事が多い。ここでは紹介しないですが。
そういうわけで以下、具体的な書き方。
■ 基本形
const { src, dest } = requore('gulp'); const default = () => src(`path/to/src/files`).pipe(dest(`path/to/dest`)); module.exports = { default };
ばりシンプル🥰
ちなみにdefault
で外出ししたやつが gulp
実行時に呼ばれる。
以下のようにやるとgulp hoge
で呼べるようになる。
const hoge = () => src(...).pipe(dest(...)); module.exports = { hoge };
各タスクの基本的な流れは3.9.1時代と変わらない。src
でファイルを指定してやって、pipe
で様々な処理を行って最終的にdest
の中で吐き出し先を指定してやるという感じ。
src
に複数渡したいときは今まで通り配列で渡せばオッケー👌globで渡せます。
3.9.1時代もそうだったけど、src
からの処理をきちんとreturnしてやる必要がある。
例)sassの場合
const { src, dest } = requore('gulp'); const sass = require('gulp-sass'); const sassGlob = require('gulp-sass-glob'); const sourcemaps = require('gulp-sourcemaps'); const please = require('gulp-pleeease'); // 僕は基本めんどいのでpleeeaseでsassの処理やってる const styles = () => src(`${DIR.SRC_ASSETS}sass/**/*.{sass,scss}`) .pipe(sourcemaps.init()) .pipe(plumber()) .pipe(sassGlob()) .pipe( sass({ outputStyle: ':expanded' }).on('error', sass.logError) ) .pipe( please({ sass: false, minifier: false, rem: false, pseudoElements: false, mqpacker: true }) ) .pipe(sourcemaps.write('./')) .pipe(dest(`${DIR.DEST_ASSETS}css`));
例にするには長々した記述のタスクだった。
■ parallel
とseries
並列処理と直列処理。
上記の感じで設定したタスクを渡すだけなのでスーパー簡単。
const { src, dest, series, parallel } = require('gulp'); const del = require('del'); // ejsなどの処理を書いておく // parallelに書いたやつは並列で走る const devTask = parallel(ejs, styles, scripts, imageMin); const clean = dir => del([dir]); // seriesで書いたやつは直列で走るので、これだと、clean.bind(null, DIR.DEST) => devTaskの順で走る。 const build = series(clean.bind(null, DIR.DEST), devTask);
■ watch
watchだけ結構癖があるというか、watchの場合は何も返さない。
ただ発火させるだけでいい。
watchもおんなじ感じで行ける。
const watchEjs = () => watch(`${DIR.SRC}**/*.ejs`, series(ejs, reload)); const watchSass = () => watch(`${DIR.SRC_ASSETS}sass/**/*.{sass,scss}`, series(styles, reload)); const watchJs = () => watch(`${DIR.SRC_ASSETS}js/**/*.js`, series(scripts, reload)); const watches = parallel(watchEjs, watchSass, watchJs); const dev = series(build, devServer, watches); module.exports = { default: dev }
■ browserSync
こいつは最近公式に乗った気がするけど、gulp4で使う場合は引数でdone
を受け取って、処理後にそれを発火させる必要がある。
const browserSync = require('browser-sync'); const devServer = done => { browserSync.init({ server: { baseDir: DIR.DEST }, ghostMode: { clicks: true, forms: true, scroll: false } }); done(); }; const reload = done => { browserSync.reload(); done(); };
これでwatchなんかの文脈で使ってもうまいことreloadしてくれる。
■ その他
gulp-ejs
こいつはgulp4から自分で拡張子の名前を変えることができなくなってやがる。
ので、gulp-renameを入れて別途拡張子の変更をしてやる必要がある。
const { src, dest } = require('gulp'); const plumber = require('gulp-plumber'); const gulpEjs = require('gulp-ejs'); const gulpRename = require('gulp-rename'); const ejs = () => src([`${DIR.SRC}**/*.ejs`, `!${DIR.SRC}_inc/**/*.ejs`]) .pipe(plumber()) .pipe(gulpEjs({ INC: Path.resolve(__dirname, `${DIR.SRC}_inc`) + '/' })) .pipe(gulpRename({ extname: '.html' })) .pipe(dest(DIR.DEST));
そんなとこですかね。
だいたいそんな感じでいけます。
関数ベースで組み立てられるので僕としては書いてて割と楽しい。
あと、結構スッキリ書けるようになったと思う。
今回の記述とってきたレポジトリはぼくのgithubに上がってるのでわかんないところあれば、参考にどうぞ