精通gulp的關(guān)鍵:文件路徑匹配模式globs

簡單說來尝艘,gulp的api非常簡單。只有4個锣险,他們分別是gulp.src gulp.dest gulp.task gulp.watch 因此旬昭,想要簡單的使用gulp很容易篙螟,但是想要將gulp使用到得心應(yīng)手的地步并不是一件簡單的事情。 而其中最關(guān)鍵的地方在于问拘,對nodejs文件路徑匹配模式globs的理解遍略。

gulp的4個api中:

  1. gulp.task創(chuàng)建一個任務(wù)
  2. gulp.src表示創(chuàng)建的任務(wù)是針對文件目錄中的那些位置
  3. gulp.dest表示目標文件被處理完畢之后會在哪個位置重新生成
  4. gulp.watch表示監(jiān)聽那些位置文件的變化

除了task,其他三個api都與文件路徑密切相關(guān)骤坐,而gulp.src與gulp.watch更是直接以golbs為第一個參數(shù)绪杏, gulp的各個插件需要知道自己處理的是那些位置的文件,而golbs則負責(zé)指定需要被處理文件的位置

每個人對前端的理解有所差異或油,造成了前端的項目結(jié)構(gòu)也是各不一樣寞忿,因此golbs的配置也就顯得更加重要 下面就一起來了解一下驰唬,golbs的匹配規(guī)則顶岸。

粗略讀一遍可能并不能掌握腔彰,所以建議大家收藏起來,留著以后慢慢看

匹配文件中0個或者多個字符辖佣,但是不會匹配路徑中的分隔符霹抛,除非路徑分隔符出現(xiàn)在末尾 例如下面的寫法

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

// 匹配./style目錄下所有的文件
./style/*.*

// 只要層級相同,可以匹配任意目錄下的任意js文件 比如./style/a/b.js
./style/*/*.js

匹配文件路徑中的0個或者多個層級的目錄卷谈,需要單獨出現(xiàn)杯拐,如果出現(xiàn)在末尾,也可匹配文件

// 匹配style目錄及其所有子目錄下的所有js文件世蔗,如能匹配
// ./style/a.js
// ./style/lib/res.js
// ./style/mudules/b/a.js
./style/**/*.js

// 匹配style目錄下的所有目錄和文件端逼,比如能匹配
// ./style/a.js
// ./style/bb
// ./style/images/c.png
./style/**/*

//? 匹配一個字符,不會匹配路徑分隔符
// 能匹配文件名只有一個字符的js文件污淋,如a.js, b.js ,但不能匹配文件名為2個字符及其以上的js的文件
?.js
[...] 由多個規(guī)則組成的數(shù)組顶滩,可以匹配數(shù)組中符合任意一個子項的文件,當(dāng)子項中第一個字符為!或者^時寸爆,表示不匹配該規(guī)則

// 匹配style目錄下的a0.js, a1.js, a2.js, a3.js
'./style/a[0-3].js'

// 除開node_modules目錄之外礁鲁,匹配項目根目錄下的所有html文件
['./**/*.html', '!node_modules/**']

{...} 展開模式,根據(jù)里面的內(nèi)容展開為多個規(guī)則赁豆,能匹配所有展開之后的規(guī)則 將上面的例子擴展一下仅醇,可以如下寫

// 除開build,simple,images,node_modules目錄,匹配根目錄下所有的html與php文件
['./**/*.{html, php}', '!{build, simple, images, node_modules}/**']
!(pattern|pattern|pattern) 每一個規(guī)則用pattern表示魔种,這里指排除符合這幾個模式的所有文件

// 匹配排除文件名為一個字符的js文件析二,以及排除jquery.js之后的所有js文件
'./style/!(?|jquery).js'

// 排除build與node_modules目錄,并排除其他目錄下以下劃線_開頭的html與php文件务嫡,匹配其余的html與php文件
// 這種比較復(fù)雜的規(guī)則在實際開發(fā)中會常常用到甲抖,需要加深了解
['./**/!(_)*.{html, php}', '!{build, node_modules}/**']

?(pattern|pattern|pattern) 匹配括號中給定的任一模式0次或者1次

// 匹配style目錄下的a.js, a2.js, b.js
// 不能組合
// 匹配0次或者1次
'./style/?(a|a2|b).js'

@(pattern|pattern|pattern) 匹配多個模式中的任一個

// 匹配style目錄下的a.js, b.js, c.js
// 不能組合
// 匹配一次,不能為空心铃,注意與?的區(qū)別
'./style/@(a|b|c).js'

+(pattern|pattern|pattern) 匹配括號中給定任一模式1次或者多次准谚,這幾個模式可以組合在一起匹配

// 可以匹配style目錄下的a.js, a2.js, b.js
// 也可以匹配他們的組合 ab.js, aa2.js, a2b.js等
// 至少匹配一次,為空不匹配
'./style/+(a|a2|b).js'

(pattern|pattern|pattern) 匹配括號中給定任一模式0次或者多次去扣,這幾個模式可以組合在一起匹配

// 可以匹配style目錄下的a.js, b.js, c.js
// 也可以匹配他們的組合 ab.js, bc.js, ac.js
// 匹配0次或者多次
'./style/*(a|b|c).js'

幾乎能用到的規(guī)則就都在上面了柱衔,在實際使用的時候,我們需要根據(jù)自己的實際情況來使用 只要掌握了globs模式愉棱,距離精通gulp也不太遠了唆铐。

API

gulp.src(globs[, options])

徹底了解了globs,那么回過頭來學(xué)習(xí)gulp的這幾個api就變得非常簡單奔滑。 gulp.src指定gulp任務(wù)的目標文件位置 它的參數(shù)中艾岂,第一個參數(shù)globs為必選,中括號表示可選參數(shù)朋其,options為一個配置json對象 globs用于指定目標文件的位置王浴,在上面已經(jīng)做過史上最詳細的介紹脆炎,這里對option做一個簡單的介紹即可

gulp.src('./**/!(_).{php, html}', {
    buffer: true,
    read: true,
    base: './'
})
options.buffer

類型: Boolean 默認:true 如果該項被設(shè)置為false,那么將會以stream方式返回file.contents氓辣,而不是文件buffer的形式秒裕。 這在處理一些大文件的時候非常有用。 另外需要注意點是钞啸,gulp插件可能不支持stream

options.read

類型: Boolean 默認: true 如果被設(shè)置為false几蜻,那么file.contents會返回空值(null) 也就是并不會去讀取文件

options.base

類型: String 默認值: 第一個參數(shù)目錄中,glob匹配模式之前的路徑 理解base至關(guān)重要体斩,它將影響到文件處理完畢后梭稚,新文件生成的目錄 我們需要結(jié)合gulp.dest來理解它。

比如在一個路徑為static/scripts/libs的目錄中絮吵,有一個js組件叫做dialog.js

// 匹配static/scripts/libs/dialog.js哨毁,并將base解析成 static/scripts
gulp.src('static/scripts/**/*.js')
  .pipe(minify())

  // 處理完畢的文件,將會用build替換掉base源武,即為 build/libs/dialog.js
  .pipe(gulp.dest('build'));

// 手動設(shè)置base的值
gulp.src('static/scripts/**/*.js', { base: 'static' })
  .pipe(minify())

  // 使用build替換base扼褪,結(jié)果為 build/scripts/libs/dialog.js
  .pipe(gulp.dest('build'));
gulp.dest(path[, options])

能被pipe進來,并且將會寫文件粱栖。會重新輸出所有數(shù)據(jù)话浇。 也就是說會新建處理完畢之后的文件。 我們可以將他pipe到多個文件夾闹究。如果文件夾不存在幔崖,則會自動新建。 關(guān)于使用方法渣淤,可以結(jié)合上面的例子進行理解赏寇。

指定的路徑用于替換gulp.src參數(shù)options中的base,結(jié)果就是新文件的位置

gulp.dest的options沒怎么使用過价认,感覺沒上面用嗅定,就略過了。

gulp.task(name[, deps], fn)

定義個gulp任務(wù)

gulp.task('somename', function() {
  // dosomething
})

name 類型:string 任務(wù)的名字用踩,如果你需要在命令行中運行你的某些任務(wù)渠退,那么不要在任務(wù)名字中使用空格
deps 類型: array 一個包含任務(wù)列表的數(shù)組,這些任務(wù)會在你當(dāng)前任務(wù)運行之前完成

gulp.task('mytask', ['array', 'of', 'task', 'names'], function() {
// dosomething
})
請一定要確保你所依賴的任務(wù)列表中的任務(wù)都使用了正確的異步執(zhí)行方式:使用一個 callback脐彩,或者返回一個 promise 或 stream碎乃。

fn 該函數(shù)定義任務(wù)所需要執(zhí)行的一些操作。通常來說惠奸,它會是這樣中形式

gulp.src().pipe(someplugin())

異步任務(wù)支持 如果fn能夠做到以下其中一點梅誓,就可以異步執(zhí)行了

接受一個callback

// 在 shell 中執(zhí)行一個命令
var exec = require('child_process').exec;
gulp.task('jekyll', function(cb) {
  // 編譯 Jekyll
  exec('jekyll build', function(err) {
    if (err) return cb(err); // 返回 error
    cb(); // 完成 task
  });
});

返回一個stream

gulp.task('somename', function() {
  var stream = gulp.src('client/**/*.js')
    .pipe(minify())
    .pipe(gulp.dest('build'));
  return stream;
});

或者返回一個promise

var Q = require('q');

gulp.task('somename', function() {
  var deferred = Q.defer();

  // 執(zhí)行異步的操作
  setTimeout(function() {
    deferred.resolve();
  }, 1);

  return deferred.promise;
});

默認的,task 將以最大的并發(fā)數(shù)執(zhí)行,也就是說梗掰,gulp 會一次性運行所有的 task 并且不做任何等待删豺。如果你想要創(chuàng)建一個序列化的 task 隊列,并以特定的順序執(zhí)行愧怜,你需要做兩件事:1. 給出一個提示,來告知 task 什么時候執(zhí)行完畢 2.并且再給出一個提示妈拌,來告知一個 task 依賴另一個 task 的完成拥坛。

對于這個例子,讓我們先假定你有兩個 task尘分,"one" 和 "two"猜惋,并且你希望它們按照這個順序執(zhí)行:

a 在 "one" 中,你加入一個提示培愁,來告知什么時候它會完成:可以再完成時候返回一個 callback著摔,或者返回一個 promise 或 stream,這樣系統(tǒng)會去等待它完成定续。

b 在 "two" 中谍咆,你需要添加一個提示來告訴系統(tǒng)它需要依賴第一個 task 完成。

因此私股,這個例子的實際代碼將會是這樣:

var gulp = require('gulp');

// 返回一個 callback摹察,因此系統(tǒng)可以知道它什么時候完成
gulp.task('one', function(cb) {
    // 做一些事 -- 異步的或者其他的
    // 如果 err 不是 null 或 undefined,則會停止執(zhí)行倡鲸,且注意供嚎,這樣代表執(zhí)行失敗了
    cb(err);
});

// 定義一個所依賴的 task 必須在這個 task 執(zhí)行之前完成
gulp.task('two', ['one'], function() {
    // 'one' 完成后
});

gulp.task('default', ['one', 'two']);
gulp.watch(glob [, options], tasks) 或 gulp.watch(glob [, options, cb])

監(jiān)視文件,并且可以在文件發(fā)生改動時候做一些事情峭状。它總會返回一個 EventEmitter 來發(fā)射(emit) change 事件克滴。

gulp.watch(glob[, options], tasks)

glob與options略過。

tasks 類型: 數(shù)組 需要在文件變動后執(zhí)行的一個或者多個通過 gulp.task() 創(chuàng)建的 task 的名字优床,

var watcher = gulp.watch('js/**/*.js', ['uglify','reload']);
watcher.on('change', function(event) {
  console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
gulp.watch(glob[, options, cb])

glob與options略過

cb(event) 類型: Function 每次變動需要執(zhí)行的回調(diào)函數(shù)

gulp.watch('js/**/*.js', function(event) {
  console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});

callback 會被傳入一個名為 event 的對象劝赔。這個對象描述了所監(jiān)控到的變動:

event.type 類型: String 發(fā)生變動的行為類型: added, changed, deleted

event.path 類型: String 觸發(fā)該事件的文件路徑

好啦,gulp的api與最關(guān)鍵的globs都介紹完了胆敞,基本上gulp也算是掌握完畢了望忆。 接下來我們要做的事情就是逐步去了解完成各種任務(wù)的插件了。很多插件都比較簡單竿秆, 在npm上都能夠找到使用方法启摄,所以也就沒什么好擔(dān)心的了。

轉(zhuǎn)自http://yangbo5207.github.io/gulp/2016/08/10/new.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幽钢,一起剝皮案震驚了整個濱河市歉备,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匪燕,老刑警劉巖蕾羊,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喧笔,死亡現(xiàn)場離奇詭異,居然都是意外死亡龟再,警方通過查閱死者的電腦和手機书闸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來利凑,“玉大人浆劲,你說我怎么就攤上這事“С海” “怎么了牌借?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長割按。 經(jīng)常有香客問我膨报,道長,這世上最難降的妖魔是什么适荣? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任现柠,我火速辦了婚禮,結(jié)果婚禮上弛矛,老公的妹妹穿的比我還像新娘晒旅。我一直安慰自己,他們只是感情好汪诉,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布废恋。 她就那樣靜靜地躺著,像睡著了一般扒寄。 火紅的嫁衣襯著肌膚如雪鱼鼓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天该编,我揣著相機與錄音迄本,去河邊找鬼。 笑死课竣,一個胖子當(dāng)著我的面吹牛嘉赎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播于樟,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼公条,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了迂曲?” 一聲冷哼從身側(cè)響起靶橱,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后关霸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體传黄,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年队寇,在試婚紗的時候發(fā)現(xiàn)自己被綠了膘掰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡佳遣,死狀恐怖识埋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情苍日,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布窗声,位于F島的核電站相恃,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏笨觅。R本人自食惡果不足惜拦耐,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望见剩。 院中可真熱鬧杀糯,春花似錦、人聲如沸苍苞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽羹呵。三九已至骂际,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冈欢,已是汗流浹背歉铝。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凑耻,地道東北人太示。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像香浩,于是被迫代替她去往敵國和親类缤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • gulpjs是一個前端構(gòu)建工具邻吭,與gruntjs相比呀非,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單,學(xué)...
    依依玖玥閱讀 3,149評論 7 55
  • gulpjs是一個前端構(gòu)建工具岸裙,與gruntjs相比猖败,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單降允,學(xué)...
    井皮皮閱讀 1,291評論 0 10
  • gulpjs是一個前端構(gòu)建工具恩闻,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù)剧董,API也非常簡單幢尚,學(xué)...
    小裁縫sun閱讀 921評論 0 3
  • gulpjs是一個前端構(gòu)建工具,與gruntjs相比翅楼,gulpjs無需寫一大堆繁雜的配置參數(shù)尉剩,API也非常簡單,學(xué)...
    build1024閱讀 527評論 0 0
  • 流程 1. 輸入命令(可以使用git bash或者命令控制臺cmd) npm install -g gulp 安裝...
    神秘者007閱讀 639評論 0 0