gulp 和grunt一样,都是任务自动管理工具,和grunt相比,gulp更加好用,配置也更加灵活。


1、安装

gulp也是基于nodejs的,同样可以通过npm安装,

全局安装

npm install -g gulp

在项目中安装

npm install gulp --save-dev

2、两个例子

创建名为gulpfile.js,在这个文件中通过gulp命令定义gulp 任务,在gulpfile.js添加如下代码:

var gulp =require('gulp'),
   uglify =require('gulp-uglify');

gulp.task('minify',function(){
   gulp.src('js/app.js').pipe(uglify()).pipe(gulp.dest('build'))
});

需要先安装gulp-uglify, 命令如下:

npm install gulp-uglify  --save-dev

然后再该目录下简历一个js目录,在这个目录下建一个app.js文件,键入内容:

function test(){
 var info= "This is a gulp information"
 return info.indexOf("gulp");
}

这时候就可以看下 效果了然后再解释其中的流程。命令如下:

gulp minify

稍等一下,会看到如下效果:

Gulp in action_gulp

流程到底是什么样子的?我们先分析一下:

首先,先加载gulp和gulp-uglify插件,然后定义一个名字为minify的task,当这个task被调用时,会运行第二个匿名方法。最后,方法中的代码才是真正要实现的功能,gulp是采用流的方式,从一个功能点流向另一个功能点。gulp.src()参数是一个字符串,指向一个或多个文件,它会创建一个指向文件的流对象,这些对象会被传递到uglify方法,返回一个包含压缩代码的文件对象,然后返回的对象传递给gulp.dest(),用来保存文件。

上面的例子是执行一个任务,如果是多个任务,先看下面的代码:

gulp.task('js', function () {
   return gulp.src('js/*.js')
      .pipe(jshint())
      .pipe(uglify())
      .pipe(concat('app.js'))
      .pipe(gulp.dest('build'));
});

运行之前,先安装 gulp, gulp-jshint, gulp-uglify and gulp-concat上面的代码分别进行jshint,uglify,concat处理。

3、方法解释

(1)gulp.src()

    这个方法主要产生数据流,参数是对应一个或者多个的字符串,一般有几种形式:

        js/app.js 完整匹配一个文件

   js/*.js  匹配js目录下的所有js文件

   js/**/*.js  匹配js文件夹下的所有js文件,包括子文件夹

   !js/app.js 除了js/app.js以外的所有文件

   *.+(js|css)匹配根目录下的js或者css文件

(2)定义task

使用gulp.tash()来定义一个task,当定义一个简单任务时,这个方法接受两个参数:task的名字和要执行的方法。

 gulp.task('greet', function () {
   console.log('Hello world!');
  });

还可以执行一系列的任务:

gulp.task('build', ['css', 'js', 'imgs']);

build任务有三个任务组成,这三个任务都是异步执行的,所以无法保证js的任务在css任务执行完才开始执行。要是想实现这样的效果也不是不可能的,如果想在某个任务执行前执行某个任务,可以通过指定依赖的方式,例子说明:

gulp.task('css', ['greet'], function () {
   // Deal with CSS here
});

上面代码的意思是,等task greet执行完才开始执行task css。

(3)默认的task

gulp.task('default', function () {
   // Your default task
});

(4)监控文件

gulp也提供了监控文件内容变化的功能,当文件变化时运行一个或多个task,

gulp.task('watch', function () {
   gulp.watch('templates/*.tmpl.html', ['build']);
});

当templates目录下的html文件变化时,会执行build任务。当然你也可以将上面的task改造一下,将事件对象event传进去:

gulp.watch('templates/*.tmpl.html', function (event) {
   console.log('Event type: ' + event.type); // added, changed, or deleted
   console.log('Event path: ' + event.path); // The path of the modified file
});

gulp.watch()还有一个比较好的特性,就是返回一个watcher,使用watcher来注册事件,看一个例子:

var watcher = gulp.watch('templates/*.tmpl.html', ['build']);
watcher.on('change', function (event) {
   console.log('Event type: ' + event.type); // added, changed, or deleted
   console.log('Event path: ' + event.path); // The path of the modified file
});

当然除了change事件还有其他的事件:

 end: 当文件变化后还没有出发任何的回调函数

 error:文件有错误

 ready:文件被搜索到后,开始监视

 nomatch:没有匹配到任何文件

watcher还包含其他的方法:end(),files(), files(), add(), remove()

4 插件

1、gulp完整的插件可以访问http://gulpjs.com/plugins/ 查看,在前面的例子中我们已经使用 gulp-jshint, gulp-uglify and gulp-concat插件,

var gulp = require('gulp'),
    jshint = require('gulp-jshint'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat');

gulp.task('js', function () {
   return gulp.src('js/*.js')
      .pipe(jshint())
      .pipe(jshint.reporter('default'))
      .pipe(uglify())
      .pipe(concat('app.js'))
      .pipe(gulp.dest('build'));
});

如果gulp的插件很多,一个一个require进来还是挺麻烦的,像grunt一样,gulp也有插件可以一次性加载所有的gulp plugins,即gulp-load-plugins:

var gulpLoadPlugins = require('gulp-load-plugins'),
    plugins = gulpLoadPlugins();

当然也可以写成一行,

var plugins = require('gulp-load-plugins')();

这个插件也是从package.json中读取gulp 插件的信息,假设package.json的devDependencies 字段中有各个插件的版本信息

{
   "devDependencies": {
      "gulp-concat": "~2.2.0",
      "gulp-uglify": "~0.2.1",
      "gulp-jshint": "~1.5.1",
      "gulp": "~3.5.6"
   }
}

2、插件实例

gulp-livereload模块用于自动刷新浏览器,反映出源码的最新变化,但是要借助浏览器插件

var gulp = require('gulp'),
    less = require('gulp-less'),
    livereload = require('gulp-livereload'),
    watch = require('gulp-watch');

gulp.task('less', function() {
   gulp.src('less/*.less')
      .pipe(watch())
      .pipe(less())
      .pipe(gulp.dest('css'))
      .pipe(livereload());
});

参考:

http://www.smashingmagazine.com/2014/06/11/building-with-gulp/

https://github.com/gulpjs/gulp/blob/master/docs/API.md

https://github.com/vohof/gulp-livereload