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
gulp
if installed globallynpm rm --global gulp rm /usr/share/man/man1/gulp.1
-
Install/Update
gulp-cli
to the latest version globallysudo npm install --global gulp-cli
Note: 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.log
Note: Installing the latest version of
gulp-cli
is 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
gulp
in 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.task
fromgulp.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.watch
fromgulp.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 viarequireDir
do 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-sequence
or other plugins that depend ongulp.hasTask
, they won't work for Gulp 4.0, as this API is removed in favor ofgulp.series
andgulp.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.