Gulp 4.0 Upgrade Guide
Gulp is a streaming build system, and 4.0 is the next major release of Gulp. Here is an upgrade guide for your reference.
Motivation
-
If you are using node 7 or later, you have to use gulp 4.
Gulp <4.0 depends on old version of graceful-fs (<3.0.0) which is incompatible with node >=7.0.
npm WARN deprecated [email protected]: graceful-fs v3.0.0 and before will fail on node releases >= v7.0. Please update to graceful-fs@^4.0.0 as soon as possible. Use 'npm ls graceful-fs' to find it in the tree.
Thus if you are going to work with node >=7.0, you have to upgrade your installation of gulp to 4.0.
Upgrade the Installation
-
Remove the old version of
gulpif installed globallynpm rm --global gulp rm /usr/share/man/man1/gulp.1 -
Install/Update
gulp-clito the latest version globallysudo npm install --global gulp-cliNote: If you run into following errors when installing
gulp-cli, don't forget to runrm /usr/share/man/man1/gulp.1, and then try again./usr/bin/gulp -> /usr/lib/node_modules/gulp-cli/bin/gulp.js npm ERR! Linux 3.4.0+ npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "install" "-g" "gulp-cli" npm ERR! node v7.2.0 npm ERR! npm v3.10.9 npm ERR! path /usr/share/man/man1/gulp.1 npm ERR! code EEXIST npm ERR! Refusing to delete /usr/share/man/man1/gulp.1: ../../../lib/node_modules/gulp/gulp.1 symlink target is not controlled by npm /usr npm ERR! File exists: /usr/share/man/man1/gulp.1 npm ERR! Move it away, and try again. npm ERR! Please include the following file with any support request: npm ERR! /home/zzz.buzz/npm-debug.logNote: Installing the latest version of
gulp-cliis required, or you may run into the following error:[19:56:57] Using gulpfile ~/zzz.buzz/gulpfile.js /usr/lib/node_modules/gulp/bin/gulp.js:129 gulpInst.start.apply(gulpInst, toRun); ^ TypeError: Cannot read property 'apply' of undefined at /usr/lib/node_modules/gulp/bin/gulp.js:129:19 at _combinedTickCallback (internal/process/next_tick.js:67:7) at process._tickCallback (internal/process/next_tick.js:98:9) at Module.runMain (module.js:607:11) at run (bootstrap_node.js:420:7) at startup (bootstrap_node.js:139:9) at bootstrap_node.js:535:3 -
Uninstall the old version of
gulpin project directorynpm rm gulp --save-dev -
Install the 4.0 version of
gulp// Use https protocol npm install --save-dev https://github.com/gulpjs/gulp#4.0 // or use git protocol npm install --save-dev gulpjs/gulp#4.0
That's it. Check your installation with this:
$ gulp -v
[01:06:42] CLI version 1.2.2
[01:06:42] Local version 4.0.0-alpha.2
Upgrade gulpfile.js
Gulp 4.0 introduces many incompatible API changes. (That's what a major release implies anyway.)
To fix them, just run gulp tasks, and follow the error messages.
Here are some common errors and corresponding solutions:
-
AssertionError: Task function must be specified
This is caused by API change in
gulp.taskfromgulp.task(name [, deps] [, fn])togulp.task([name,] fn).If you were writing
gulp.task('alias', ['mytask']); gulp.task('zzz', ['dep1'], function() { ... }); gulp.task('buzz', ['dep1', 'dep2'], function() { ... }); gulp.task('zzzbuzz', ['dep1', 'dep2', 'dep3']);Change them to the following respectively
gulp.task('alias', gulp.task('mytask')); gulp.task('zzz', gulp.series('dep1', function() { ... })); gulp.task('buzz', gulp.series(gulp.parallel('dep1', 'dep2'), function() { ... })); gulp.task('zzzbuzz', gulp.parallel('dep1', 'dep2', 'dep3'));See gulp/API.md at v3.9.1 · gulpjs/gulp vs. gulp/API.md at v4.0.0 · gulpjs/gulp.
-
Error: watching …: watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)
This is caused by API change in
gulp.watchfromgulp.watch(glob [, opts], tasks)orgulp.watch(glob [, opts, cb])togulp.watch(globs[, opts][, fn]).The solution to this is much the same as the previous one, and is also said in the error message.
e.g. Change
gulp.watch('*.js', ['taskzzz']);to
gulp.watch('*.js', gulp.task('taskzzz')); // or gulp.watch('*.js', gulp.series('taskzzz')); // or gulp.watch('*.js', gulp.parallel('taskzzz'));See gulp/API.md at v3.9.1 · gulpjs/gulp vs. gulp/API.md at 4.0 · gulpjs/gulp.
-
AssertionError: Task never defined: …
Gulp 4.0 requires that task should already be registered when using task names.
If you were defining the broadest/alias tasks before defining component tasks
gulp.task('t', ['mytask']); gulp.task('task', gulp.series('mytask')); gulp.task('mytask', function() { ... });Then you need to put the component tasks first.
gulp.task('mytask', function() { ... }); gulp.task('t', gulp.series('mytask')); gulp.task('task', gulp.series('mytask'));And if you were using
requireDir, make sure that tasks imported viarequireDirdo not depend on each other, or tasks with dependencies are imported in proper order. -
TypeError: gulp.hasTask is not a function
If you were using
run-sequenceor other plugins that depend ongulp.hasTask, they won't work for Gulp 4.0, as this API is removed in favor ofgulp.seriesandgulp.parallel.e.g. Change this
gulp.task('build', function(cb) { runSequence( 'jekyll-build', 'modernizr', [ 'minify', 'autoprefixer' ], 'serve', cb); });to
gulp.task('build', gulp.series( 'jekyll-build', 'modernizr', gulp.parallel( 'minify', 'autoprefixer' ), 'serve'));
There are also some other changes which may or may not break your existing code without throwing an error.
For example, the underlying watching library used by gulp.watch has been switched from gaze to chokidar, which may or may not cause incompatibility for your gulpfile. Though this did cause problems for me.
In gulp before 4.0, I was watching on some css files, auto-prefixing properties on file changes, and writing back to their original location. It worked like a charm, but in gulp 4.0 with chokidar, this causes infinite recursive calls. If you run into this as well, a staging area may be employed to overcome this.