一、简介

1、简介

Gulp是一个工具包,使用它可以自动完成开发过程中重复或耗时的任务。

2、相关概念

  • Vinyl

Vinyl是描述文件的元数据对象。Vinyl实例的主要属性pathcontents用来描述文件系统中文件的核心内容。Vinyl对象可以被用来描述来自本地文件系统或其他远程存储等多种来源的文件。

  • Vinyl适配器

    Vinyl提供了一种描述文件的方法,同时也需要一种访问这些文件的方法,可以使用Vinyl适配器来访问每个文件源:

    • src(globs, [options])

    读取文件,返回一个虚拟文件对象流(Vinyl对象)。

    • dest(folder, [options])

    写入文件,消费一个Vinyl对象。

  • 任务

每个gulp任务都是一个JavaScript函数,定义任务的语法如下:

gulp.task(name[, deps], fn)

Gulp提供了两种强大的任务组合方式series()parallel(),这两种方法都接受任意数量的任务函数或组合操作,而且它们可以嵌套在它们自己内部,也可以相互嵌套到任何深度。

如果任务需要顺序执行,则使用series()方法;如果要使任务并发运行,则使用parallel()方法。

  • Globs匹配规则

    glob是一个用来匹配文件路径的普通字符串(字面值)或通配符字符串,例如:***!src()方法需要一个glob字符串或一个globs数组来确定操作哪些文件;当使用globs数组时,将会按照数组元素顺序进行匹配。

    • *

    匹配单个片段中任意数量的字符(包括空);例如:*.js匹配index.js但不匹配scripts/index.jsscripts/nested/index.js

    • **

    匹配任意数量的跨段的字符(包括空);例如:scripts/**/*.js的匹配限制在scripts/目录下,它将匹配scripts/index.jsscripts/nested/index.jsscripts/nested/twice/index.js等。

    • !

    由于globs是按数组顺序匹配的,因此非!(non-negative)的glob后面至少要跟一个!(negative)的glob;第一个找到一组匹配内容,然后!的glob从这些结果中删除一部分。

      ['scripts/**/*.js', '!scripts/vendor/**']
    

二、安装

首先需要安装nodeJs相关环境。
  • 安装gulp命令行工具
npm install -g gulp-cli
  • 初始化

创建一个新的文件夹并使用npm init命令创建package.json文件:

npm init
  • 在devDependencies中安装gulp
npm install --save-dev gulp

三、样例

在项目根目录中需创建一个gulpfile.js文件;此处最早是使用3.9版本的gulp,后来升级到4.0后,在样例的js中都加了回调函数(callback),否则在执行gulp命令后会有提示:The following tasks did not complete: defaultDid you forget to signal async completion?

1、Hello World

gulpfile.js

var gulp = require('gulp');
gulp.task('default', function(){
	console.log('hello world!');
});

由于任务可能包含异步代码,gulp4.0需要在完成任务时调用传递的回调函数表示任务完成:

var gulp = require('gulp');
gulp.task('default', function(cb){
	console.log('hello world!');
	cb();
});

2、多个任务

gulpfile.js中定义了多个任务,可以使用gulp xxx来执行指定的任务:

var gulp = require('gulp');
gulp.task('default', function(cb){
	console.log('hello world!');
	cb();
});

gulp.task('test', function(cb){
	console.log('this is a test case!');
	cb();
});

3、处理文件

var gulp = require('gulp');
gulp.task('fileTest', function(cb){
	gulp.src('src/foo.js').pipe(gulp.dest('dist/bar'));
	cb();
});

执行gulp fileTest,运行完成后会看到根目录下生成了dist目录,并将foo.js复制到了dist/bar目录下。

4、任务依赖

gulp.task('one', function(){
	setTimeout(function(){
		console.log('one is done');
	},2000);
});

gulp.task('two', ['one'], function(){
	console.log('two is done');
});

gulp4.0版本写法:

  • series
var gulp = require('gulp');
gulp.task('one', function(done){
	console.log('The task one starts execution');
	setTimeout(function(){
		console.log('one is done');
		done();
	},2000);
});
gulp.task('two', gulp.series('one', function(done){
	console.log('two is done');
	done();
}));

下面的写法与上面等价,需使用gulp build运行:

const { series } = require('gulp');

function one(done){
	console.log('The task one starts execution');
	setTimeout(function(){
		console.log('one is done');
		done();
	},2000);
}

function two(done){
	console.log('two is done');
	done();
}

exports.build = series(one, two);
  • parallel

如果使用parallel组合任务,则可以使任务并行运行:

const { parallel } = require('gulp');

function one(done){
	console.log('The task one starts execution');
	setTimeout(function(){
		console.log('one is done');
		done();
	},2000);
}

function two(done){
	console.log('two is done');
	done();
}

exports.build = parallel(one, two);

效果如下:

5、监听文件

可以使用watch()方法监视globs匹配的文件,当发生变化时运行相应的任务,语法如下:

watch(globs, [options], [task])
var gulp = require('gulp');
function doSomething(cb){
	console.log('doSomething');
	cb();
};
function doOtherSomething(cb){
	console.log('doOtherSomething');
	cb();
};
function watchFiles(){
	gulp.watch('src/**/*.js', gulp.series(doSomething, doOtherSomething));
};
exports.build = watchFiles;

运行gulp build命令,之后修改src/foo.js文件,会看到执行了相应的任务:

6、调用Webpack

gulpfile.js:

const gulp = require('gulp');
const config = require('./webpack.config.js');
const webpack = require('webpack');

gulp.task('webpack', function(cb){

	webpack(config).run(function(){
		//callback
	});

	cb();
});
参考资料

Quick Start - gulp.js

task() - gulp.js

Creating Tasks - gulp.js

gulp - npm

gulp详细入门教程

Gulp + Webpack or JUST Webpack?