一、gulp简介
gulp是一个自动化构建工具。在开发过工程中,能够使用gulp对项目进行自动构建,大大提高工作效率。
二、安装gulp
在安装gulp之前先要确认已经正确安装了node.js,然后在项目根目录下安装gulp:
$ npm install gulp
三、gulp函数接口介绍
在编写gulp配置文件gulpfile之前,需要先了解常见的函数接口:
1. gulp.src()
gulp的工作过程是这样的,首先通过gulp.src()获取我们想要处理的文件的stream(文件流);然后,通过.pipe方法将stream导入到引用的gulp插件中进行相应的处理;最后通过gulp.dest()方法将处理后的流写入到文件中。
从gulp工作过程中可以看到,gulp.src()主要用来从文件中获取文件流。gulp.dest()函数原型如下:
gulp.src(globs[, options]
globs是文件的匹配路径和匹配形式。下面列举了部分常用的匹配形式:
(1)js/test.js //精确匹配文件
(2)js/*.js //匹配js目录下所有后缀为.js的文件
(3)js/**/*.js //匹配js目录及其子目录下所有后缀为.js的文件
(4)!js/test.js //从匹配结果中排出js目录下的test.js文件
语法:gulp.src(globs[, options])
globs
:文件匹配模式(类似正则表达式),用来匹配文件路径(包括文件名)options
:为可选参数。通常情况下我们不需要用到
gulp.src('**/*.js')
- 1
匹配模式
Gulp 内部使用了 node-glob 模块来实现其文件匹配功能
单匹配模式
匹配符 | code | 匹配 | 不匹配 | 备注 |
* |
* |
a.b , x.y , abc , abc/ |
a/b.js |
不匹配/ ,除非/ 出现在末尾 |
*.* |
a.b , x.y |
abc |
匹配所有带后缀的文件 | |
*/*/*.js |
a/b/c.js , x/y/z.js |
a/b.js , a/b/c/d.js |
匹配固定层级目录 | |
** |
** |
abc , a/b , a/b.js , a/b/c , a/b/c.js |
匹配所有的目录和文件 | |
**/*.js |
a.js , a/b.js , a/b/c.js |
匹配所有目录下的 .js 文件 |
||
a/**/z |
a/z , a/b/z , a/b/c/z , a/b/c/d/z |
|||
a/**b/z |
a/b/z , a/nb/z |
a/c/nb/z ,
|
** 单独出现才能匹配多级目录 |
|
? |
?.js |
a.js , b.js , c.js |
占位符匹配,不匹配 / |
|
a?? |
a.b , abc |
ab/ |
占位符与字符搭配使用 | |
[] |
[abc].js |
a.js , b.js , c.js |
ab.js , xyz.js |
整个 [] 只匹配一个字符 |
[^abc].js [!abc].js |
x.js , y.js |
a.js , b.js , c.js |
排除匹配字符 |
多匹配模式(同时使用多种匹配)
1. 类正则
表达式 | 备注 |
---|---|
!(pattern|pattern|pattern) |
匹配任何与括号中给定的任一模式都不匹配的 |
?(pattern|pattern|pattern) |
匹配括号中给定的任一模式0次或1次,类似于js正则中的 (pattern|pattern|pattern)? |
+(pattern|pattern|pattern) |
匹配括号中给定的任一模式至少1次,类似于js正则中的 (pattern|pattern|pattern)+ |
*(pattern|pattern|pattern) |
匹配括号中给定的任一模式0次或多次,类似于js正则中的 (pattern|pattern|pattern)* |
@(pattern|pattern|pattern) |
匹配括号中给定的任一模式1次,类似于js正则中的 (pattern|pattern|pattern) |
2. 数组
- 使用数组匹配多种模式
gulp.src(['js/*.js', 'css/*.css', '*.html'])
- 1
- 使用数组 + 排除模式
排除模式不能出现在数组的第一个元素中
gulp.src([*.js,'!b*.js']) // 匹配所有js文件,但排除掉以b开头的js文件
gulp.src(['!b*.js',*.js]) // 不排除任何文件,因为排除模式不能出现在数组的第一个元素中
- 1
- 2
3. 展开模式
以 {}
作为定界符,根据它里面的内容,会展开为多个模式,
最后匹配的结果为所有展开的模式相加起来得到的结果 !
1. a{b, c}d
展开为:abc
,acd
2. a{b,}c
展开为:abc
,ac
3. a{0..3}c
展开为:a0c
,a1c
,a2c
4. a{b, c{d, e}f}g
展开为:abg
,acdfg
,acefg
5. a{b, c}d{e, f}g
展开为:abdeg
,acdeg
,abdeg
,abdfg
2. gulp.task()
gulp.task()函数用来构建任务。函数原型为:
gulp.task(name[, deps], fn)
name是所构建的任务名称。fn是任务所要执行的函数,gulp具体的工作过程是在fn中进行的。示例:
var webpack = require('gulp-webpack'); var config = require('./webpack.config'); gulp.task('webpack', function() { return webpack(config) .pipe(uglify()) .pipe(gulp.dest('./dist/js')); });
上面的代码是我在项目中使用的部分。该部分是webpack与gulp的联合使用,第一次看到别人用时,感觉发现了新大陆。task参数function中webpack会首先执行同一目录下的webpack.config.js配置文件,对代码进行模块打包;然后,返回打包后的所有文件的文件流;文件流通过pipe进入到uglify插件后进行压缩;最后,文件流通过gulp.dest写入到设置的目录下。
3.gulp.dest()
gulp.dest()是对文件流的输出进行设置。函数原型为:
gulp.dest(path[, options])
path是文件输出路径设置。注意:path只能生成文件的目录,不能生成文件的名称,不能生成文件的名称,不能生成文件的名称,不能生成文件的名称,重要的事说四遍。而最终生成的文件的名称是由gulp.src传入的文件名决定。下面会由示例的。
文件最终生成的路径也需要注意:
(1)如果gulp.src(path)中的path带有通配符,则生成的路径由gulp.dest(path_dest)中的path_dest代替path通配符前面的部分组成。例如:
gulp.src('js/*/test.js') //假设匹配到的文件为js/source/test.js .pipe(gulp.dest('dist')); //最终生成的文件为 dist/source/test.js
(2)如果gulp.src(path)中的path没有带通配符,则生成的路径由gulp.dest(path_dest)中的path_dest与gulp.src引入的文件名组成。例如:
gulp.src('js/test.js') .pipe(gulp.dest('dist')); //最终生成的文件为 dist/test.js
四、常用的gulp插件
1. gulp-uglify插件
引入:
var uglify = require('gulp-uglify');
作用:对js文件流进行压缩。
gulp.task('server_test', function() { return gulp.src(server/app.js) .pipe(uglify()) .pipe(gulp.dest('./dist/js')); });
上面代码中的uglify()会对流过它的js数据流进行压缩,然后有gulp.dest写入到js目录下。
2. gulp-less插件
引入:
var less = require('gulp-less');
作用:对less文件流进行压缩
gulp.task('server_test', function() { return gulp.src(server/device.less) .pipe(less()) .pipe(gulp.dest('./dist/less')); });
上面代码中的less()会对流过它的less数据流进行压缩,然后有gulp.dest写入到less目录下。
3. gulp-minify-css插件
引入:
var minifyCSS = require('gulp-minify-css');
作用:对css文件流进行压缩
gulp.task('server_test', function() { return gulp.src(server/control.css) .pipe(minifyCSS()) .pipe(gulp.dest('./dist/css')); });
上面代码中的minifyCSS()会对流过它的css数据流进行压缩,然后有gulp.dest写入到css目录下。
gulp中有很多插件,具体根据需要来选择。
要想使用好gulp.dest()这个方法,就要理解给它传入的路径参数与最终生成的文件的关系。
gulp的使用流程一般是这样子的:首先通过gulp.src()方法获取到我们想要处理的文件流,然后把文件流通过pipe方法导入到gulp的插件中,最后把经过插件处理后的流再通过pipe方法导入到gulp.dest()中,gulp.dest()方法则把流中的内容写入到文件中,这里首先需要弄清楚的一点是,我们给gulp.dest()传入的路径参数,只能用来指定要生成的文件的目录,而不能指定生成文件的文件名,它生成文件的文件名使用的是导入到它的文件流自身的文件名,所以生成的文件名是由导入到它的文件流决定的,即使我们给它传入一个带有文件名的路径参数,然后它也会把这个文件名当做是目录名,例如:
1 var gulp = require('gulp'); 2 gulp.src('script/jquery.js') 3 .pipe(gulp.dest('dist/foo.js')); 4 //最终生成的文件路径为 dist/foo.js/jquery.js,而不是dist/foo.js
要想改变文件名,可以使用插件gulp-rename
下面说说生成的文件路径与我们给gulp.dest()方法传入的路径参数之间的关系。
gulp.dest(path)生成的文件路径是我们传入的path参数后面再加上gulp.src()中有通配符开始出现的那部分路径。例如:
1 var gulp = reruire('gulp'); 2 //有通配符开始出现的那部分路径为 **/*.js 3 gulp.src('script/**/*.js') 4 .pipe(gulp.dest('dist')); //最后生成的文件路径为 dist/**/*.js 5 //如果 **/*.js 匹配到的文件为 jquery/jquery.js ,则生成的文件路径为 dist/jquery/jquery.js
1 gulp.src('script/avalon/avalon.js') //没有通配符出现的情况 2 .pipe(gulp.dest('dist')); //最后生成的文件路径为 dist/avalon.js 3 4 //有通配符开始出现的那部分路径为 **/underscore.js 5 gulp.src('script/**/underscore.js') 6 //假设匹配到的文件为script/util/underscore.js 7 .pipe(gulp.dest('dist')); //则最后生成的文件路径为 dist/util/underscore.js 8 9 gulp.src('script/*') //有通配符出现的那部分路径为 * 10 //假设匹配到的文件为script/zepto.js 11 .pipe(gulp.dest('dist')); //则最后生成的文件路径为 dist/zepto.js
通过指定gulp.src()方法配置参数中的base属性,我们可以更灵活的来改变gulp.dest()生成的文件路径。
当我们没有在gulp.src()方法中配置base属性时,base的默认值为通配符开始出现之前那部分路径,例如:
1 gulp.src('app/src/**/*.css') //此时base的值为 app/src 2 //上面我们说的gulp.dest()所生成的文件路径的规则,其实也可以理解成,用我们给gulp.dest()传入的路径替换掉gulp.src()中的base路径,最终得到生成文件的路径。 3 4 gulp.src('app/src/**/*.css') //此时base的值为app/src,也就是说它的base路径为app/src 5 //设该模式匹配到了文件 app/src/css/normal.css 6 .pipe(gulp.dest('dist')) //用dist替换掉base路径,最终得到 dist/css/normal.css 所以改变base路径后,gulp.dest()生成的文件路径也会改变 7 8 gulp.src(script/lib/*.js) //没有配置base参数,此时默认的base路径为script/lib 9 //假设匹配到的文件为script/lib/jquery.js 10 .pipe(gulp.dest('build')) //生成的文件路径为 build/jquery.js 11 12 gulp.src(script/lib/*.js, {base:'script'}) //配置了base参数,此时base路径为script 13 //假设匹配到的文件为script/lib/jquery.js 14 .pipe(gulp.dest('build')) //此时生成的文件路径为 build/lib/jquery.js
注意:用gulp.dest()把文件流写入文件后,文件流仍然可以继续使用。
使用gulp-htmlmin压缩html,可以压缩页面javascript、css,去除页面空格、注释,删除多余属性等操作。
1 var gulp = require('gulp'), 2 htmlmin = require('gulp-htmlmin'); 3 4 gulp.task('testHtmlmin', function () { 5 var options = { 6 removeComments: true,//清除HTML注释 7 collapseWhitespace: true,//压缩HTML 8 collapseBooleanAttributes: true,//省略布尔属性的值 <input checked="true"/> ==> <input /> 9 removeEmptyAttributes: true,//删除所有空格作属性值 <input id="" /> ==> <input /> 10 removeScriptTypeAttributes: true,//删除<script>的type="text/javascript" 11 removeStyleLinkTypeAttributes: true,//删除<style>和<link>的type="text/css" 12 minifyJS: true,//压缩页面JS 13 minifyCSS: true//压缩页面CSS 14 }; 15 gulp.src('src/html/*.html') 16 .pipe(htmlmin(options)) 17 .pipe(gulp.dest('dist/html')); 18 });