blog
blog copied to clipboard
比Grunt更好用的前端自动化工具——Gulp
比Grunt更好用的前端自动化工具——Gulp
- 前端构建工具
- 基于node.js
- 流式
一、安装
全局安装:
npm install -g gulp
项目目录中安装:
nmp install --save-dev gulp
编辑package.json文件, 或者执行
npm init
生成package.json,然后执行
npm install
二、API
gulp和插件安装完毕后, 在目录中创建配置文件gulpfile.js。
gulp.src()
指定数据源文件,产生数据流。参数是文件,可以是数组
gulp.src(["js/**/*.js",[!js/**/*.min.js]])
gulp.dest()
将管道的输出写入文件,同事将这些输出继续输出,因此可以多次调用dest方法,将输出写入多个目录。目录不存在则新建。
gulp.task()
用于任务定义。第一个参数是任务名称,第二个参数是任务函数,指定任务具体的操作。
task方法还可以指定按顺序运行的一组任务,例如:
gulp.task("build",["css","js","imgs"]);
上例中,定义一个任务build,执行三个子任务“css”、“js”、“imgs”。这些任务不是同时进行的,不能认为“js”任务结束时“css”任务已经结束。
如果需要确保一个任务在另一个任务结束后执行,可将函数和任务组合结合起来指定依赖关系。例如:
gulp.task("css",["greet"], function(){
//
});
上例中,定义“css”任务,执行前检查greet任务是否执行完毕,完毕在调用第三个参数定义的函数。
default tasks 执行gulp任务是在命令行中输入:
gulp + taskName
如果不加taskName,就会报“Task ‘default’ is not in your gulpfile”,找不着默认任务。最好在配置文件末,写上默认任务,执行起来比较方便。例如:
gulp.task("scripts",function(){
//...
});
...
gulp.task("default", ["scripts"]);
gulp.watch()
监听文件的状态,文件发生变化执行某些任务。 用法:
gulp.task("watch",function(){
gulp.watch("js/src/**/*.js",["copy","concat","uglify"])
})
上例中任务数组可以换成回调函数,
gulp.task("watch",function(){
gulp.watch("js/src/**/*.js",function(event){
console.log("Event type: " + event.type + " Event path" + event.path);
})
})
回调函数中打印事件类型和发生改变文件路径,type值有“added”、“deleted”、“changed”
gulp.watch可配合LiveReload、BrowserSync使用,实现文件修改浏览器立即刷新等功能
三、插件
http://gulpjs.com/plugins/
常用操作 | 插件名称 |
---|---|
文件合并 | gulp-concat |
文件拷贝 | gulp-copy |
文件替换 | gulp-replace |
JS压缩 | gulp-uglify |
语法检查 | gulp-jshint |
图片压缩 | gulp-imagemin |
CSS压缩 | gulp-cssmin |
添加注释 | gulp-wrapper |
压缩JS gulp-uglify
https://www.npmjs.com/package/gulp-uglify
举个栗子:
var gulp = require("gulp"),
uglify = require("gulp-uglify");
gulp.task("uglify",function(){
gulp.src(["src/common/*.js"])
.pipe(uglify({
mangle: {
except: ["define","require","module","exports"]
}
}))
.pipe(gulp.dest("min/common"))
});
上例中,将src/common/目录下的js进行压缩,压缩文件放到min/common/目录中。参数mangle,可以像上例中那样排除一些关键字以适用sea.js模块管理,或者赋值“false”,在压缩过程中跳过函数名使其不被压缩。
合并 gulp-concat
https://www.npmjs.com/package/gulp-concat
例子:
var gulp = require("gulp"),
concat = require("gulp-concat"),
uglify = require("gulp-uglify");
gulp.task("scripts",function(){
gulp.src(["src/common/reqData.js","src/common/util.js"])
.pipe(uglify())
.pipe(concat("base.min.js",{
newLine: "\r\n\r\n"
}))
.pipe(gulp.dest("min/common"))
});
上例中,将src/common/目录下reqData.js和util.js压缩后合并成一个文件base.min.js,参数的作用是在两个文件之间添加两个换行。
四、Stream
类似于*nix将几乎所有的设备抽象为文件一样,Node将文件访问、输入输出、http连接等几乎所有I/O都抽象成了Stream。
Linux中管道的概念
通过管道将stdout导入到stdin。command1的正确输出(stand output)作为command2的输入,然后command2的输出作为command3的输入,command1、2的输出不会显示,command3的运行结果会输出。 可以类比理解。shell中的“|”符号和gulp中的pipe()方法作用相同。
五、其他高级用法
gulp.env
gulp有个env属性可以接受参数,env属性值对应一个对象:
{ _ : [] }
"_"属性值默认是空,当指定执行任务时,它的值是任务名。 例如:
gulp compress
gulp.env是:
{ _ : ["compress"]}
同理指定多个任务,数组中就有多个值。可以获取这些任务名来执行不同的操作,例如根据任务名不同来修改不同目录
命令行传参
用法:
gulp --key1 value1 --key2 value2
获取方式和上面类似,通过gulp.env
gulp.env: { _ : [], key1: value1, key2: value2 }
针对参数使用举个例子:
var gulp = require("gulp"),
uglify = require("gulp-uglify"),
header = require("gulp-header"),
gutil = require("gulp-util");
var dir = gulp.env.dir ? gulp.env.dir : "common",
date = (new Date()).getTime();
gulp.task("default",function(){
gutil.log(gutil.colors.bgGreen("/* ------- 用 法 ------- */"));
gutil.log(gutil.colors.bgGreen("拷贝:gulp copy --dir [目录名]"));
gutil.log(gutil.colors.bgGreen("压缩:gulp jsmin --dir [目录名] "));
});
gulp.task("copy",function(){
return gulp.src("src/" + dir + "/*.js")
.pipe(header("/* timeStapmp="+ date +" */ \r\n"))
.pipe(gulp.dest("min/" + dir))
});
gulp.task("jsmin",function(){
return gulp.src("src/" + dir + "/*.js")
.pipe(uglify())
.pipe(header("/* timeStapmp="+ date +" */ \r\n"))
.pipe(gulp.dest("min/" + dir))
});
执行:
上例中,定义了两个任务"copy"和“jsmin”,两个任务都能接受一个参数,这个参数指定操作对应的目录。
六、与Grunt比较
比Grunt配置少配置简单、运行速度快
- 不生成中间文件
Gulp基于node.js的Stream机制。每个插件不能单独使用,依靠组合发挥作用,就像一条流水线,上一道工序的产出交给下一道工序,效率高。 Grunt基于文件,很多操作都要需要生成一些中间文件,这些文件在任务完成后就没用了,需要删掉。文件操作时间消耗多,还有无用文件产生。gulp配置代码量相应的也会少。
- 配置和运行在一起
变量的声明和使用挨在一起最方便。但是Gruntfile中,配置task和调用一般都离得很远,尤其是配置文件比较大的时候。
- 插件配置语法基本相同
Grunt的很多插件的配置规则有一定差别,有的看起来还有些怪异。Gulp插件配置规则基本都一样。(插件方法调用,第一个参数是文件,第二个是配置json。)
- 每个插件只专注于做一件事情
Gulp中每个插件单一职责,每个插件的配置就比较简单。 Grunt中每个插件要配置一坨。