gulpをv3系からv4へ実際に移行してみた流れをまとめました。
執筆時点でのgulpバージョンはv4.0.2になります。
移行前の状態
こちらが移行する前(v3)の状態の設定ファイルです。
/*--------------------------------------------------------
modules
--------------------------------------------------------*/
let gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
cached = require('gulp-cached'),
notify = require('gulp-notify'),
plumber = require('gulp-plumber'),
sass = require('gulp-sass'),
watch = require('gulp-watch'),
encode = require('gulp-convert-encoding'),
uglify = require('gulp-uglify'),
pleeease = require('gulp-pleeease'),
replace = require('gulp-replace'),
fs = require('fs');
//------------------------------------------------------------------------------
// PC:sass / scss / css
//------------------------------------------------------------------------------
gulp.task('pc:sass', () =>
gulp
.src(`${__dirname}/pc/**/*.scss`)
.pipe(
plumber({
errorHandler: notify.onError('<%= error.message %>')
})
)
.pipe(
sass({
outputStyle: 'expanded'
}).on('error', sass.logError)
)
.pipe(
autoprefixer({
browsers: [
'last 2 versions',
'ie >= 9',
'ChromeAndroid >= 6',
'Android >= 6',
'iOS >= 9'
]
})
)
.pipe(replace('UTF-8', 'Shift_JIS'))
.pipe(replace('utf-8', 'Shift_JIS'))
.pipe(encode({ to: 'Shift_JIS' }))
.pipe(gulp.dest(`${__dirname}/path/to/css/`))
);
//------------------------------------------------------------------------------
// SP:sass / scss / css
//------------------------------------------------------------------------------
gulp.task('sp:sass', () =>
gulp
.src(`${__dirname}/sp/**/*.scss`)
.pipe(
plumber({
errorHandler: notify.onError('<%= error.message %>')
})
)
.pipe(
sass({
outputStyle: 'expanded'
}).on('error', sass.logError)
)
.pipe(
autoprefixer({
browsers: [
'last 2 versions',
'ie >= 9',
'ChromeAndroid >= 6',
'Android >= 6',
'iOS >= 9'
]
})
)
.pipe(replace('UTF-8', 'Shift_JIS'))
.pipe(replace('utf-8', 'Shift_JIS'))
.pipe(encode({ to: 'Shift_JIS' }))
.pipe(gulp.dest(`${__dirname}/path/to/css/`))
);
//------------------------------------------------------------------------------
// PC:watch
//------------------------------------------------------------------------------
gulp.task('pc:watch', () => {
watch(`${__dirname}/pc/**/*.scss`, () => gulp.start('pc:sass'));
});
//------------------------------------------------------------------------------
// SP:watch
//------------------------------------------------------------------------------
gulp.task('sp:watch', () => {
watch(`${__dirname}/sp/**/*.scss`, () => gulp.start('sp:sass'));
});
gulp.task('pc', ['pc:watch']);
gulp.task('sp', ['sp:watch']);
gulp.task('default', ['pc', 'sp']);
使ってないプラグインなんかも読み込まれていてますがその辺は後でまとめて整理するとして
こいつをv4の書き方に直していきます。
移行スタート
まずはgulpのバージョンアップ
今入っているgulpのバージョンがv3.9.1だったので、まずはこれを最新のバージョンにアップデートします。
(パッケージのバージョンチェック・アップデートにnpm-check-updatesを使ってます。)
ncu gulp -u
npm i
v4にバージョンアップして試しにそのままgulpを実行すると、当然ですがエラーで阻まれます。
出てくるエラーを片端から潰していく
Task function must be specified
v4からタスクを呼び出す時の書き方が変わった事によるエラーです。
今回の場合だとこの辺りが原因になります。
gulp.task('pc', ['pc:watch']);
gulp.task('sp', ['sp:watch']);
gulp.task('default', ['pc', 'sp']);
pc:watch
、sp:watch
、pc
、sp
というタスクを呼び出して実行しようとしてますが、呼び出し方がv4の書き方に則ってないよって感じですね。
v4からの書き方はこうなります。
gulp.task('pc', gulp.task('pc:watch'));
gulp.task('sp', gulp.task('sp:watch'));
gulp.task('default', gulp.parallel('pc', 'sp'));
複数のタスクを同時に実行する場合は以下のどちらかを使いましょう。
gulp.series
:直列処理
gulp.parallel
:並列処理
今回使用したgulpfileだと、ここを修正しただけでとりあえずタスクが実行されるようになりました。
gulp.start is not a function
default
、pc
、sp
のタスクは無事に実行されるようになりましたがscssファイルを保存するとエラーで止まってしまいます。
v4からgulp.start
が使えなくなっているのが原因です。コードとしてはこの辺り。
//------------------------------------------------------------------------------
// PC:watch
//------------------------------------------------------------------------------
gulp.task('pc:watch', () => {
watch(`${__dirname}/pc/**/*.scss`, () => gulp.start('pc:sass'));
});
//------------------------------------------------------------------------------
// SP:watch
//------------------------------------------------------------------------------
gulp.task('sp:watch', () => {
watch(`${__dirname}/sp/**/*.scss`, () => gulp.start('sp:sass'));
});
そもそもwatch機能を使うためにgulp-watch
を使用していますが、gulp.watch
で良いのでそこも含めて書き直しましょう。
//------------------------------------------------------------------------------
// PC:watch
//------------------------------------------------------------------------------
gulp.task('pc:watch', () => {
gulp.watch(`${__dirname}/pc/**/*.scss`, gulp.task('pc:sass'));
});
//------------------------------------------------------------------------------
// SP:watch
//------------------------------------------------------------------------------
gulp.task('sp:watch', () => {
gulp.watch(`${__dirname}/sp/**/*.scss`, gulp.task('sp:sass'));
});
// ディレクトリを複数設定する場合は配列にする
gulp.task('sp:watch', () => {
gulp.watch(['path/to/hoge/*.scss', 'path/to/fuga/*.scss'], gulp.task('sp:sass'));
});
これで正常にwatchの処理も動くようになり、ひとまず以前と同じように動くようになりました。
使わなくなったgulp-watch
などを消してあげれば最低限の移行はこれで完了です。
今回は大丈夫だったけど遭遇するかもしれないエラー
今回の例として使ったgulpfileでは大丈夫でしたが、遭遇しそうなエラーの対処も書いておきます。
Task never defined: hogehoge
定義されていないtaskを実行しようとすると出ます。
v4からはgulp.task('hogehoge')
でtaskを実行する前に、そのtaskが定義されている必要があります。
記述の順番を見直してみましょう。
The following tasks did not complete
v4からはtaskの終了を明示する必要があります。
今回の場合は
gulp.task('pc:sass', () =>
gulp
.src(`${__dirname}/pc/**/*.scss`)
// 略
);
このようにコールバック関数としてgulp
を渡しているのでエラーが出ることはありませんでした。
gulp
をコールバック関数として渡せない場合は以下のようにgulp
をreturn
してあげると良いと思います。
gulp.task('pc:sass', () => {
return gulp
.src(`${__dirname}/pc/**/*.scss`)
// 略
});
もっとv4のルールに則った形にする
ここまでの段階で使えるようにはなっていますが、非推奨の書き方も含まれているためそこも直していきます。
gulp.taskは非推奨
山ほど使っているgulp.task
が現在では非推奨になっており、タスクごとに関数を定義するように言われています。
ので、その辺りを考慮して書き直すとこうなります。
//------------------------------------------------------------------------------
// PC:sass / scss / css
//------------------------------------------------------------------------------
const compilePcSass = () =>
gulp
.src(`${__dirname}/pc/**/*.scss`)
// 中略
.pipe(gulp.dest(`${__dirname}/path/to/css`));
//------------------------------------------------------------------------------
// SP:sass / scss / css
//------------------------------------------------------------------------------
const compileSpSass = () =>
gulp
.src(`${__dirname}/sp/**/*.scss`)
// 中略
.pipe(gulp.dest(`${__dirname}/path/to/css`));
//------------------------------------------------------------------------------
// PC:watch
//------------------------------------------------------------------------------
const watchPcSassFiles = () =>
gulp.watch(`${__dirname}/pc/**/*.scss`, compilePcSass);
//------------------------------------------------------------------------------
// SP:watch
//------------------------------------------------------------------------------
const watchSpSassFiles = () =>
gulp.watch(`${__dirname}/sp/**/*.scss`, compileSpSass);
exports.default = gulp.parallel(watchPcSassFiles, watchSpSassFiles);
今までdefault
タスクで実行していた内容は、exports.default
に渡してあげます。
必要なプラグインだけ読み込むようにする
一番最初に
gulp = require('gulp')
でgulp
を丸ごと読み込んでいますが、今回使っているのはsrc
、dest
、watch
、parallel
だけなのでそれ以外は不要です。
const {src, dest, watch, parallel} = require('gulp')
こうすれば必要な部分だけ読み込むことができます。
最終的に出来上がったgulpfile.js
/*--------------------------------------------------------
modules
--------------------------------------------------------*/
const { src, watch, dest, parallel } = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
notify = require('gulp-notify'),
plumber = require('gulp-plumber'),
sass = require('gulp-sass'),
encode = require('gulp-convert-encoding'),
replace = require('gulp-replace');
//------------------------------------------------------------------------------
// PC:sass / scss / css
//------------------------------------------------------------------------------
const compilePcSass = () =>
src(`${__dirname}/pc/**/*.scss`)
.pipe(
plumber({
errorHandler: notify.onError('<%= error.message %>')
})
)
.pipe(
sass({
outputStyle: 'expanded'
}).on('error', sass.logError)
)
.pipe(
autoprefixer({
browsers: [
'last 2 versions',
'ie >= 9',
'ChromeAndroid >= 6',
'Android >= 6',
'iOS >= 9'
]
})
)
.pipe(replace('UTF-8', 'Shift_JIS'))
.pipe(replace('utf-8', 'Shift_JIS'))
.pipe(encode({ to: 'Shift_JIS' }))
.pipe(dest(`${__dirname}/path/to/css/`));
//------------------------------------------------------------------------------
// SP:sass / scss / css
//------------------------------------------------------------------------------
const compileSpSass = () =>
src(`${__dirname}/sp/**/*.scss`)
.pipe(
plumber({
errorHandler: notify.onError('<%= error.message %>')
})
)
.pipe(
sass({
outputStyle: 'expanded'
}).on('error', sass.logError)
)
.pipe(
autoprefixer({
browsers: [
'last 2 versions',
'ie >= 9',
'ChromeAndroid >= 6',
'Android >= 6',
'iOS >= 9'
]
})
)
.pipe(replace('UTF-8', 'Shift_JIS'))
.pipe(replace('utf-8', 'Shift_JIS'))
.pipe(encode({ to: 'Shift_JIS' }))
.pipe(dest(`${__dirname}/path/to/css/`));
//------------------------------------------------------------------------------
// PC:watch
//------------------------------------------------------------------------------
const watchPcSassFiles = () =>
watch(`${__dirname}/pc/**/*.scss`, compilePcSass);
//------------------------------------------------------------------------------
// SP:watch
//------------------------------------------------------------------------------
const watchSpSassFiles = () =>
watch(`${__dirname}/sp/**/*.scss`, compileSpSass);
exports.default = parallel(watchPcSassFiles, watchSpSassFiles);