Gulp是前端開發(fā)過程中對代碼進行構(gòu)建的工具浊竟,合理的使用能大大的提升我們的工作效率。Gulp借鑒了unix的管道的思想(pipe),使用起來更加直觀方便瓶您。
使用前準備
gulp安裝
- 由于國內(nèi)網(wǎng)絡問題衙荐,通過npm直接安裝gulp速度會很慢,所以一般要先設置淘寶景象:
npm --registry https://registry.npm.taobao.org info underscore
- 全局安裝:
npm install --global gulp
- 作為項目的開發(fā)依賴(devDependencies)安裝:
npm install --save-dev gulp
安裝成功后在項目根目錄下創(chuàng)建一個名為 gulpfile.js 的文件(設置相關(guān)工作流):
var gulp = require('gulp');
gulp.task('default', function() {
// 將你的默認的任務代碼放在這
});
基本函數(shù)只有五個:
src方法
gulp.src(globs[, options])
說明:指定需要處理的源文件的路徑
globs:(必填 String or Array)
文件匹配模式(類似正則表達式),用來匹配文件路徑,也可以直接指定某個具體文件路徑,當有多個匹配模式時,該參數(shù)可以為一個數(shù)值.
options:(可選 Object) 可選參數(shù)
options.buffer:是否返回buffer滩届,默認值為true
options.read:是否讀取該文件,默認為true慎宾。如果設置為false丐吓,返回的file.content為null,而且不會讀取該文件趟据。
options.base:指glob開始匹配的任意目錄券犁,為后面dest定義輸出文件目錄
Gulp使用的是node-glob模塊來實現(xiàn)其文件匹配功能(node的glob模塊允許你使用 * 等符號, 來寫一個glob規(guī)則,獲取匹配對應規(guī)則的文件,是一個簡化的正折表達式):
-
* 匹配單個路徑中的0個或多個字符(不會匹配以.符號開始的字符),而且只會匹配到目錄這一層汹碱,不會去匹配目錄內(nèi)部的字符
script/* 匹配script目錄下的所有文件和目錄粘衬,但不會匹配目錄內(nèi)的文件
-
** 匹配路徑中的0個或多個字符,并且可以匹配目錄內(nèi)部字符
script/** 匹配script目錄下的所有文件和目錄,會匹配目錄下所有文件
-
? 匹配文件路徑中的一個字符(不會匹配路徑分隔符)
script/? 匹配script目錄下的是一個字符的文件或者目錄
-
[...] 匹配方括號中出現(xiàn)的字符中的任意一個咳促,當方括號中第一個字符為^或!時稚新,則表示不匹配方括號中出現(xiàn)的其他字符中的任意一個
script/k[0-1].js 匹配script目錄下的k0.js和k1.js.
script/k[!0-1].js 匹配script目錄下的以 -
!(pattern|pattern|pattern) 匹配任何與括號中給定的任一模式都不匹配的
script/!(k0|k2|app) 匹配除了k0,k2,app(包括文件和目錄)以外的文件和目錄(不會匹配到目錄內(nèi)的文件)
-
*(pattern|pattern|pattern) 匹配括號中給定的任一模式0次或多次或任意組合
script/*(k|1|2|app)b.js 匹配script目錄下k,1,2,app有關(guān)組合的任意文件,比如k1b.js,k2b.js,appb.js,kappb.js,app1b.js...等等,pattern也可以一個也不出現(xiàn)跪腹,可以匹配b.js
-
+(pattern|pattern|pattern) 匹配括號中給定的任一模式至少1次或任意組合褂删,但pattern至少出現(xiàn)一次
script/+(k|1|2|app)b.js 規(guī)則同上,但與之不同的是冲茸,不會匹配b.js
-
?(pattern|pattern|pattern) 匹配括號中給定的任一模式0次或1次,不會匹配任意組合
script/?(k|a|s)b.js 匹配script目錄下屯阀,kb.js,ab.js,sb.js,不會匹配相關(guān)組合轴术,同時允許pattern為空难衰,也可以匹配b.js
-
@(pattern|pattern|pattern) 匹配括號中給定的任一模式1次,不會匹配任意組合
script/?(k|a|s)b.js 規(guī)則同上逗栽,但不允許pattern為空盖袭,不匹配b.js
下面以一系列例子來加深理解:
* 能匹配 a.js,x.y,abc,abc/,但不能匹配a/b.js
*.* 能匹配 a.js,style.css,a.b,x.y
*/*/*.js 能匹配 a/b/c.js,x/y/z.js,不能匹配a/b.js,a/b/c/d.js
** 能匹配 abc,a/b.js,a/b/c.js,x/y/z,x/y/z/a.b,能用來匹配所有的目錄和文件
**/*.js 能匹配 foo.js,a/foo.js,a/b/foo.js,a/b/c/foo.js a/**/z 能匹配 a/z,a/b/z,a/b/c/z,a/d/g/h/j/k/z
a/**b/z 能匹配 a/b/z,a/sb/z,但不能匹配a/x/sb/z,因為**只有在規(guī)則最后出現(xiàn)才能匹配多級目錄
?.js 能匹配 a.js,b.js,c.js
a?? 能匹配 a.b,abc,但不能匹配ab/,因為?不會匹配路徑分隔符
[xyz].js 只能匹配 x.js,y.js,z.js,不會匹配xy.js,xyz.js等,整個中括號只代表一個字符
[^xyz].js 能匹配 a.js,b.js,c.js等,不能匹配x.js,y.js,z.js
當有多種匹配模式時可以使用數(shù)組
gulp.src(['js/.js','css/.css','*.html']) //使用數(shù)組的方式來匹配多種文件
使用數(shù)組的方式還有一個好處就是可以很方便的使用排除模式,在數(shù)組中的單個匹配模式前加上!即是排除模式彼宠,它會在匹配的結(jié)果中排除這個匹配鳄虱,要注意一點的是不能在數(shù)組中的第一個元素中使用排除模式
gulp.src([.js,'!b.js']) //匹配所有js文件,但排除掉以b開頭的js文件
gulp.src(['!b.js',.js]) //不會排除任何文件凭峡,因為排除模式不能出現(xiàn)在數(shù)組的第一個元素中
此外醇蝴,還可以使用展開模式。
展開模式以花括號作為定界符想罕,根據(jù)它里面的內(nèi)容悠栓,會展開為多個模式霉涨,最后匹配的結(jié)果為所有展開的模式相加起來得到的結(jié)果。
展開的例子如下:
a{b,c}d 會展開為 abd,acd
a{b,}c 會展開為 abc,ac
a{0..3}d 會展開為 a0d,a1d,a2d,a3d
a{b,c{d,e}f}g 會展開為 abg,acdfg,acefg
a{b,c}d{e,f}g 會展開為 abdeg,acdeg,abdeg,abdfg
gulp.src("script/k{1,2}.js") //會展開匹配script目錄下的k1.js,k2.js
gulp.src()方法正是用來獲取流的惭适,但要注意這個流里的內(nèi)容不是原始的文件流笙瑟,而是一個虛擬文件對象流(Vinyl files)(以stream或者buffer的格式),這個虛擬文件對象中存儲著原始文件的路徑癞志、文件名往枷、內(nèi)容等信息
task方法
gulp.task(name[,deps],fn)
說明:定義一個gulp任務
name:(必填 String)
指定任務的名稱
deps:(選填 StringArray)
在任務執(zhí)行前要執(zhí)行和完成的任務的數(shù)組
fn: (必填 Function)
任務函數(shù)
gulp.task('testLess', function () {
return gulp.src(['less/style.less'])
.pipe(less())
.pipe(gulp.dest('./css'))
})
gulp.task('minicss', ['testLess'], function () {
//minicss依賴于testLess任務,minicss一定會在testLess任務后再運行
gulp.src(['css/*.css'])
.pipe(minifyCss())
.pipe(gulp.dest(./dist/css'));
})
gulp.task('build', ['css', 'js', 'img']);
上面代碼先指定build任務,它由css凄杯、js错洁、imgs三個任務所組成,task build方法會并發(fā)執(zhí)行這三個任務戒突。每個任務都是異步調(diào)用,沒辦法保證 js的執(zhí)行時間一定是在css任務之后.
異步任務執(zhí)行(這里目前尚不明白屯碴,暫時跳過)
通過task定義的任務,如果滿足如下任意一點膊存,即可進行異步任務:
這個方法最主要是指定任務的執(zhí)行順序
dest方法
gulp.dest(path[,options])
說明:dest方法是指定處理后文件輸出寫入文件,如果目錄不存在,將會被新建
path:(必填 string or function)
指定文件輸出路徑导而,或者定義函數(shù)返回文件輸出路徑亦可;
options:(選填 Object)
有2個屬性cwd,mode
- options.cwd:(string) 指定寫入路徑的基準目錄,默認是當前目錄
- options.mode:(string) 指定寫入文件的權(quán)限,默認是0777
這個方法最主要是理解好它傳入的路徑參數(shù)與最終生成的文件關(guān)系.生成的文件名是由導入到它的文件流決定的,即使傳入一個帶有文件名的路徑參數(shù),也會把這個文件名當作是目錄名隔崎。
gulp.dest(path)生成的文件路徑是我們傳入的path參數(shù)后面再加上gulp.src()中有通配符(base的參數(shù))開始出現(xiàn)的那部分路徑:
var gulp = require('gulp');
gulp.src('script/jquery.js')
.pipe(gulp.dest('dist/foo.js'));
//最終生成的文件路徑為 dist/foo.js/jquery.js,而不是dist/foo.js
沒有通配符出現(xiàn)的情況
gulp.src('script/avalon/avalon.js')
.pipe(gulp.dest('dist'));
//最后生成的文件路徑為 dist/avalon.js
有通配符的情況
通配符開始出現(xiàn)的那部分路徑為 **/underscore.js
假設匹配到的文件為script/util/underscore.js
gulp.src('script/**/underscore.js')
.pipe(gulp.dest('dist'));
//則最后生成的文件路徑為 dist/util/underscore.js
有通配符出現(xiàn)的那部分路徑為 *
假設匹配到的文件為script/zepto.js
gulp.src('script/*')
.pipe(gulp.dest('dist'));
//則最后生成的文件路徑為 dist/zepto.js
通過指定gulp.src()方法配置參數(shù)中的base屬性今艺,我們可以更靈活的來改變gulp.dest()生成的文件路徑。
當我們沒有在gulp.src()方法中配置base屬性時爵卒,base的默認值為通配符開始出現(xiàn)之前那部分路徑虚缎,例如:
gulp.src('app/src/**/*.css') //此時base的值為 app/src
gulp.dest()所生成的文件路徑的規(guī)則,其實也可以理解成钓株,用我們給gulp.dest()傳入的路徑替換掉gulp.src()中的base路徑遥巴,最終得到生成文件的路徑。
如下例dest傳入值為dist,由于沒有設置base值享幽,所以這里的base值默認為app/src,該模式匹配到了文件 app/src/css/normal.css拾弃,dest路徑對base替換值桩,所以輸出路徑最終地址為:dist/css/normal.css
gulp.src('app/src/**/*.css')
.pipe(gulp.dest('dist'))
//用dist替換掉base路徑,最終得到dist/css/normal.css
watch方法
gulp.watch(glob[, opts], tasks) 或
gulp.watch(glob[, opts, cb])
說明:watch方法用于指定需要監(jiān)視的文件,一旦這些文件發(fā)生變化它總會返回一個 EventEmitter 來發(fā)射(emit) change 事件豪椿。
glob:(必填 String or Array)
需要處理的源文件匹配符路徑
opts:(選填 Object)
可選的配置對象,通常不需要用到
tasks:(必填 Array)
文件變化后要執(zhí)行的任務
gulp.task('uglify',function(){ //do something });
gulp.task('reload',function(){ //do something });
gulp.watch('js/**/*.js',['uglify','reload']);
cb:(選填 Function)
回調(diào)函數(shù)奔坟,代替指定的任務(其中回調(diào)函數(shù)包含一些基本信息:type為變化類型,path為變化文件路徑)
gulp.watch('js/**/*.js',
function(event){
//變化類型added為新增,deleted為刪除,changed為改變
console.log(event.type);
//變化的文件的路徑
console.log(event.path);
}
);
常用插件
gulp-uglify
說明:壓縮js代碼
安裝:npm install --save-dev gulp-uglify
gulp-minify-css
說明:壓縮css代碼
安裝:npm install --save-dev gulp-minify-css
gulp-minify-html
說明:壓縮html文件
安裝:npm install --save-dev gulp-minify-html
gulp-jshint
說明:用來檢查js代碼
安裝:npm install --save-dev gulp-jshint
gulp-concat
說明:把多個文件合并為一個文件,我們可以用它來合并js或css文件等搭盾,這樣就能減少頁面的http請求數(shù)了
安裝:npm install --save-dev gulp-concat
gulp-less
說明:編譯less
安裝:npm install --save-dev gulp-less
gulp-sass
說明:編譯sass
安裝:npm install --save-dev gulp-sass
gulp-imagemin
說明:圖片壓縮
安裝:npm install --save-dev gulp-imagemin
gulp-load-plugins
說明:按package.json加載文件
安裝:npm install --save-dev gulp-load-plugins
gulp-rename
說明:用來重命名文件流中的文件
安裝:npm install --save-dev gulp-rename
gulp-minify-css
說明:要壓縮css文件時可以使用該插件
安裝:npm install --save-dev gulp-minify-css
gulp-del
說明:刪除文件
安裝:npm install --save-dev gulp del