因为之前一直有人给我推荐gulp,说他这里好哪里好的。实际上对我来说够用就行。grunt熟悉以后实际上他的配置也不难,说到效率的话如果真是要完整打包上线也不在乎那么几秒时间,对于项目来说线上效率关键,但是线下效率只要不是让人无法忍受页没有太多问题。不过不管怎么说,需要亲自用过gulp之后才能品评他和grunt之间的优劣。不废话,直接上实例。
本人自建了一个前端目录结构,后续的例子都是以这个目录结构为准。dest是我们打包压缩结果保存目录,现在是空的。以后每完成一个实例,我们就会清空一下dest目录,保证下一个实例的结果和实例代码对应。
1. 第一个简单的gulp打包
1)需要安装nodejs:http://www.cnblogs.com/chuaWeb/p/nodejs-npm.html
本人的nodejs工程目录为F:chuaNodejs(后续所有相对路径都是相对于这个目录)
2) 创建package.json文件,可以使用npm init命令来创建。然后在其中的devDependencies中包含gulp相关的插件依赖。我的package.json是这样的
{ "name": "my-gulp", "version": "1.0.0", "description": "demo", "dependencies": { "express": "3.x" }, "devDependencies": { "gulp-clean": "^0.3.2", "gulp": "^3.9.1", "gulp-concat": "^2.6.0", "gulp-mini-css": "^0.0.3", "gulp-uglify": "^1.5.3", "gulp-requirejs-optimize": "^0.3.2" }, "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "author": "chua", "license": "ISC" }
随着我们使用npm安装的插件添加,里面的内容随之更改。
命令行到nodejs目录(需要系统管理员权限,不然后续过程中会报错)安装gulp作为项目的开发依赖(devDependencies,当然也可以用其他方式安装):npm install --save-dev gulp
gulp有很多官方插件可以去查看安装:http://gulpjs.com/plugins/。
但是下面的几个插件基本上都要用到,可以先安装
gulp:这个是必须安装的,没有它,其它组件都用不了(注意watch组件直接集成在gulp中了,无需额外安装watch组件)
gulp-mini-css :压缩css使用的
gulp-uglify:压缩、混淆js文件用的
3) 在nodejs工程目录下建一个gulpfile.js,内容为
var gulp = require('gulp'), mincss = require('gulp-mini-css'), uglify = require('gulp-uglify'); var src_css = './src/css', dest_css = './dest/css', src_js = './src/js', dest_js = './dest/js'; gulp.task('mincss', function () { gulp.src(src_css+'/**/*.css') .pipe(mincss()) .pipe(gulp.dest(dest_css)); }); gulp.task('minjs', function () { gulp.src(src_js+'/**/*.js') .pipe(uglify()) .pipe(gulp.dest(dest_js)); }); gulp.task('watch', function () { gulp.watch(src_css+'/**/*.css',['mincss']); gulp.watch(src_js+'/**/*.js',['minjs']); }); gulp.task('default',function(){ gulp.run('minjs','mincss'); gulp.run('watch'); });
可以看到里面和nodejs代码写法类似。
4)命令行运行:gulp
执行结果
可以看到我们将src的js/css都压缩打包到了对应的dest文件夹下
注意:gulp命令和gulp default等价。而且这个时候监听任务是一直执行着的,每当有相应的文件改动那么就会执行相应的任务。
5)源码分析:
//注册一个叫做mincss的任务,命令行gulp mincss可以运行这个任务 //需要说明的是代码中”*”代表的是一层文件,而”**”代表要递归其子文件夹 gulp.task('mincss', function () { gulp.src(src_css+'/**/*.css')//返回了src/css/下的全部(包含子文件夹里的).css文件流;gulp.src(str)返回了一个可读的stream .pipe(mincss())//执行gulp-mini-css组件任务,压缩所有css文件流 .pipe(gulp.dest(dest_css));//将文件流写入到 COMPRESS/css 里的对应路径下;gulp.dest(str)返回一个可写的stream }); //注册名为watch的任务 gulp.task('watch', function () { gulp.watch(src_css+'/**/*.css',['mincss']);//监听src/css/下的全部.css文件,若有改动则执行名为'mincss'任务 gulp.watch(src_js+'/**/*.js',['minjs']);//监听src/css/下的全部.js文件,若有改动则执行名为'minjs'任务 }); //每个gulpfile.js里都应当有一个dafault任务,它是缺省任务入口,运行gulp的时候实际只是调用该任务(从而来调用其它的任务) gulp.task('default',function(){ gulp.run('minjs','mincss');//立刻执行'minjs','mincss'这两个任务;gulp.run(tasks)表示运行对应的任务 gulp.run('watch');//立刻执行'watch'任务 });
比较grunt而言,确实更容易上手。
2. 合并压缩
有些时候为了减少请求需要合并多个文件,且需要压缩。使用uglify和concat即可做到这一点。所以还要下载concat插件:npm install gulp-concat --save-dev
gulpfile.js代码
var gulp = require('gulp'), uglify = require('gulp-uglify'), concat = require('gulp-concat'); var src_js = './src/js', dest_js = './dest/js'; gulp.task('minjs', function () { gulp.src(src_js+'/**/*.js') .pipe(uglify())//压缩 .pipe(concat("all.min.js"))//合并 .pipe(gulp.dest(dest_js)); }); gulp.task('watch', function () { gulp.watch(src_js+'/**/*.js',['minjs']);//监听src/css/下的全部.js文件,若有改动则执行名为'minjs'任务 }); gulp.task('default',['minjs','watch']);
这里文件会压缩的顺序按照字母顺序并层层深入的顺序压缩到all.min.js中。
这里我们看到gulp.task的用法有多种,gulp.task(name[, deps], fn),deps是一个包含任务列表的数组,这些任务会在你当前任务运行之前完成。详情参考:http://www.gulpjs.com.cn/docs/api/
如果要按照指定的顺序压缩的话,你需要为gulp.src执行文件列表才行,gulp会按照文件列表数组中元素的顺序压缩。
gulpfile.js源码
var gulp = require('gulp'), uglify = require('gulp-uglify'), concat = require('gulp-concat'); var src_js = './src/js', dest_js = './dest/js'; gulp.task('minjs', function () { gulp.src([src_js+'/bootstrap.min.js',src_js+'/jquery.js'])//先压缩bootstrap,然后再压缩jquery .pipe(uglify()) .pipe(concat("all.min.js")) .pipe(gulp.dest(dest_js)); }); gulp.task('watch', function () { gulp.watch(src_js+'/**/*.js',['minjs']);//监听src/css/下的全部.js文件,若有改动则执行名为'minjs'任务 }); gulp.task('default',['minjs','watch']);
3. watch事件监听
watch组件包含在gulp中,不许另行下载。
我们在最开始的实例中已经用过了watch的基本用法:gulp.watch(glob,tasks)
现在来看一下另一种用法:gulp.watch(glob,callback)
gulpfile.js源码
var gulp = require('gulp'), uglify = require('gulp-uglify'), notify = require("gulp-notify"); gulp.task('minjs', function () { gulp.src('src/main.js') .pipe(uglify()) .pipe(gulp.dest("dest/")); }); gulp.task('watch', function () { gulp.watch('src/main.js',function(e){ //e有两个属性type/path if(e.type == "changed"){//added, changed, or deleted gulp.run("minjs"); console.log(e.type + ": " + e.path); } }); }); gulp.task('default',["minjs",'watch']);
可以看到函数的参数(事件)e有两个属性type和path。我们可以根据他们的值去做一些定制服务。
Gulp.watch()的另一个非常好的特性是返回watcher对象。利用watcher来监听额外的事件或者向watch中添加文件。