前端構(gòu)建工具gulpjs的使用介紹及技巧

gulpjs是一個前端構(gòu)建工具,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單,學(xué)習(xí)起來很容易馏谨,而且gulpjs使用的是nodejs中stream來讀取和操作數(shù)據(jù)别渔,其速度更快。如果你還沒有使用過前端構(gòu)建工具惧互,或者覺得gruntjs太難用的話哎媚,那就嘗試一下gulp吧。

本文導(dǎo)航:

gulp的安裝

開始使用gulp

gulp的API介紹

一些常用的gulp插件

1喊儡、gulp的安裝

首先確保你已經(jīng)正確安裝了nodejs環(huán)境拨与。然后以全局方式安裝gulp:

npm install -g gulp

全局安裝gulp后,還需要在每個要使用gulp的項(xiàng)目中都單獨(dú)安裝一次艾猜。把目錄切換到你的項(xiàng)目文件夾中买喧,然后在命令行中執(zhí)行:

npm install gulp

如果想在安裝的時(shí)候把gulp寫進(jìn)項(xiàng)目package.json文件的依賴中,則可以加上--save-dev:

npm install --save-dev gulp

這樣就完成了gulp的安裝匆赃。至于為什么在全局安裝gulp后淤毛,還需要在項(xiàng)目中本地安裝一次,有興趣的可以看下stackoverflow上有人做出的回答:why-do-we-need-to-install-gulp-globally-and-locally算柳、what-is-the-point-of-double-install-in-gulp低淡。大體就是為了版本的靈活性,但如果沒理解那也不必太去糾結(jié)這個問題,只需要知道通常我們是要這樣做就行了蔗蹋。

2何荚、開始使用gulp

2.1 建立gulpfile.js文件

就像gruntjs需要一個Gruntfile.js文件一樣,gulp也需要一個文件作為它的主文件猪杭,在gulp中這個文件叫做gulpfile.js餐塘。新建一個文件名為gulpfile.js的文件,然后放到你的項(xiàng)目目錄中胁孙。之后要做的事情就是在gulpfile.js文件中定義我們的任務(wù)了唠倦。下面是一個最簡單的gulpfile.js文件內(nèi)容示例,它定義了一個默認(rèn)的任務(wù)涮较。

var gulp = require('gulp');

gulp.task('default',function(){

? ? console.log('hello world');

});

此時(shí)我們的目錄結(jié)構(gòu)是這樣子的:

├── gulpfile.js

├── node_modules

│ └── gulp

└── package.json

2.2 運(yùn)行g(shù)ulp任務(wù)

要運(yùn)行g(shù)ulp任務(wù)稠鼻,只需切換到存放gulpfile.js文件的目錄(windows平臺請使用cmd或者Power Shell等工具),然后在命令行中執(zhí)行g(shù)ulp命令就行了狂票,gulp后面可以加上要執(zhí)行的任務(wù)名候齿,例如gulp task1,如果沒有指定任務(wù)名闺属,則會執(zhí)行任務(wù)名為default的默認(rèn)任務(wù)慌盯。

3、gulp的API介紹

使用gulp掂器,僅需知道4個API即可:gulp.task(),gulp.src(),gulp.dest(),gulp.watch()亚皂,所以很容易就能掌握,但有幾個地方需理解透徹才行国瓮,我會在下面一一說明灭必。為了避免出現(xiàn)理解偏差,建議先看一遍官方文檔。

3.1 gulp.src()

在介紹這個API之前我們首先來說一下Grunt.js和Gulp.js工作方式的一個區(qū)別。Grunt主要是以文件為媒介來運(yùn)行它的工作流的晾浴,比如在Grunt中執(zhí)行完一項(xiàng)任務(wù)后朗伶,會把結(jié)果寫入到一個臨時(shí)文件中,然后可以在這個臨時(shí)文件內(nèi)容的基礎(chǔ)上執(zhí)行其它任務(wù),執(zhí)行完成后又把結(jié)果寫入到臨時(shí)文件中,然后又以這個為基礎(chǔ)繼續(xù)執(zhí)行其它任務(wù)...就這樣反復(fù)下去。而在Gulp中秘狞,使用的是Nodejs中的stream(流),首先獲取到需要的stream蹈集,然后可以通過stream的pipe()方法把流導(dǎo)入到你想要的地方谒撼,比如Gulp的插件中,經(jīng)過插件處理后的流又可以繼續(xù)導(dǎo)入到其他插件中雾狈,當(dāng)然也可以把流寫入到文件中廓潜。所以Gulp是以stream為媒介的,它不需要頻繁的生成臨時(shí)文件,這也是Gulp的速度比Grunt快的一個原因辩蛋。再回到正題上來呻畸,gulp.src()方法正是用來獲取流的,但要注意這個流里的內(nèi)容不是原始的文件流悼院,而是一個虛擬文件對象流(Vinyl files)伤为,這個虛擬文件對象中存儲著原始文件的路徑、文件名据途、內(nèi)容等信息绞愚,這個我們暫時(shí)不用去深入理解,你只需簡單的理解可以用這個方法來讀取你需要操作的文件就行了颖医。其語法為:

gulp.src(globs[, options])

globs參數(shù)是文件匹配模式(類似正則表達(dá)式)位衩,用來匹配文件路徑(包括文件名),當(dāng)然這里也可以直接指定某個具體的文件路徑熔萧。當(dāng)有多個匹配模式時(shí)糖驴,該參數(shù)可以為一個數(shù)組。

options為可選參數(shù)佛致。通常情況下我們不需要用到贮缕。

下面我們重點(diǎn)說說Gulp用到的glob的匹配規(guī)則以及一些文件匹配技巧。

Gulp內(nèi)部使用了node-glob模塊來實(shí)現(xiàn)其文件匹配功能俺榆。我們可以使用下面這些特殊的字符來匹配我們想要的文件:

* 匹配文件路徑中的0個或多個字符感昼,但不會匹配路徑分隔符,除非路徑分隔符出現(xiàn)在末尾

** 匹配路徑中的0個或多個目錄及其子目錄,需要單獨(dú)出現(xiàn)罐脊,即它左右不能有其他東西了定嗓。如果出現(xiàn)在末尾,也能匹配文件爹殊。

? 匹配文件路徑中的一個字符(不會匹配路徑分隔符)

[...] 匹配方括號中出現(xiàn)的字符中的任意一個蜕乡,當(dāng)方括號中第一個字符為^或!時(shí)奸绷,則表示不匹配方括號中出現(xiàn)的其他字符中的任意一個梗夸,類似js正則表達(dá)式中的用法

!(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)

下面以一系列例子來加深理解

* 能匹配 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,因?yàn)橹挥袉?*單獨(dú)出現(xiàn)才能匹配多級目錄

?.js 能匹配 a.js,b.js,c.js

a?? 能匹配 a.b,abc,但不能匹配ab/,因?yàn)樗粫ヅ渎窂椒指舴?/p>

[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

當(dāng)有多種匹配模式時(shí)可以使用數(shù)組

//使用數(shù)組的方式來匹配多種文件

gulp.src(['js/*.js','css/*.css','*.html'])

使用數(shù)組的方式還有一個好處就是可以很方便的使用排除模式畔派,在數(shù)組中的單個匹配模式前加上!即是排除模式铅碍,它會在匹配的結(jié)果中排除這個匹配,要注意一點(diǎn)的是不能在數(shù)組中的第一個元素中使用排除模式

gulp.src([*.js,'!b*.js']) //匹配所有js文件线椰,但排除掉以b開頭的js文件

gulp.src(['!b*.js',*.js]) //不會排除任何文件胞谈,因?yàn)榕懦J讲荒艹霈F(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

3.2 gulp.dest()

gulp.dest()方法是用來寫文件的午阵,其語法為:

gulp.dest(path[,options])

path為寫入文件的路徑

options為一個可選的參數(shù)對象,通常我們不需要用到

要想使用好gulp.dest()這個方法享扔,就要理解給它傳入的路徑參數(shù)與最終生成的文件的關(guān)系底桂。

gulp的使用流程一般是這樣子的:首先通過gulp.src()方法獲取到我們想要處理的文件流,然后把文件流通過pipe方法導(dǎo)入到gulp的插件中惧眠,最后把經(jīng)過插件處理后的流再通過pipe方法導(dǎo)入到gulp.dest()中籽懦,gulp.dest()方法則把流中的內(nèi)容寫入到文件中,這里首先需要弄清楚的一點(diǎn)是锉试,我們給gulp.dest()傳入的路徑參數(shù)猫十,只能用來指定要生成的文件的目錄,而不能指定生成文件的文件名呆盖,它生成文件的文件名使用的是導(dǎo)入到它的文件流自身的文件名拖云,所以生成的文件名是由導(dǎo)入到它的文件流決定的,即使我們給它傳入一個帶有文件名的路徑參數(shù)应又,然后它也會把這個文件名當(dāng)做是目錄名宙项,例如:

var gulp = require('gulp');

gulp.src('script/jquery.js')

? ? .pipe(gulp.dest('dist/foo.js'));

//最終生成的文件路徑為 dist/foo.js/jquery.js,而不是dist/foo.js

要想改變文件名,可以使用插件gulp-rename

下面說說生成的文件路徑與我們給gulp.dest()方法傳入的路徑參數(shù)之間的關(guān)系株扛。

gulp.dest(path)生成的文件路徑是我們傳入的path參數(shù)后面再加上gulp.src()中有通配符開始出現(xiàn)的那部分路徑尤筐。例如:

var gulp = reruire('gulp');

//有通配符開始出現(xiàn)的那部分路徑為 **/*.js

gulp.src('script/**/*.js')

? ? .pipe(gulp.dest('dist')); //最后生成的文件路徑為 dist/**/*.js

//如果 **/*.js 匹配到的文件為 jquery/jquery.js ,則生成的文件路徑為 dist/jquery/jquery.js

再舉更多一點(diǎn)的例子

gulp.src('script/avalon/avalon.js') //沒有通配符出現(xiàn)的情況

? ? .pipe(gulp.dest('dist')); //最后生成的文件路徑為 dist/avalon.js

//有通配符開始出現(xiàn)的那部分路徑為 **/underscore.js

gulp.src('script/**/underscore.js')

? ? //假設(shè)匹配到的文件為script/util/underscore.js

? ? .pipe(gulp.dest('dist')); //則最后生成的文件路徑為 dist/util/underscore.js

gulp.src('script/*') //有通配符出現(xiàn)的那部分路徑為 *

? ? //假設(shè)匹配到的文件為script/zepto.js

.pipe(gulp.dest('dist')); //則最后生成的文件路徑為 dist/zepto.js

通過指定gulp.src()方法配置參數(shù)中的base屬性,我們可以更靈活的來改變gulp.dest()生成的文件路徑洞就。

當(dāng)我們沒有在gulp.src()方法中配置base屬性時(shí)盆繁,base的默認(rèn)值為通配符開始出現(xiàn)之前那部分路徑,例如:

gulp.src('app/src/**/*.css') //此時(shí)base的值為 app/src

上面我們說的gulp.dest()所生成的文件路徑的規(guī)則旬蟋,其實(shí)也可以理解成油昂,用我們給gulp.dest()傳入的路徑替換掉gulp.src()中的base路徑,最終得到生成文件的路徑倾贰。

gulp.src('app/src/**/*.css') //此時(shí)base的值為app/src,也就是說它的base路徑為app/src

? ? //設(shè)該模式匹配到了文件 app/src/css/normal.css

? ? .pipe(gulp.dest('dist')) //用dist替換掉base路徑冕碟,最終得到 dist/css/normal.css

所以改變base路徑后,gulp.dest()生成的文件路徑也會改變

gulp.src(script/lib/*.js) //沒有配置base參數(shù)匆浙,此時(shí)默認(rèn)的base路徑為script/lib

? ? //假設(shè)匹配到的文件為script/lib/jquery.js

? ? .pipe(gulp.dest('build')) //生成的文件路徑為 build/jquery.js

gulp.src(script/lib/*.js, {base:'script'}) //配置了base參數(shù)安寺,此時(shí)base路徑為script

? ? //假設(shè)匹配到的文件為script/lib/jquery.js

? ? .pipe(gulp.dest('build')) //此時(shí)生成的文件路徑為 build/lib/jquery.js

用gulp.dest()把文件流寫入文件后,文件流仍然可以繼續(xù)使用首尼。

3.3 gulp.task()

gulp.task方法用來定義任務(wù)挑庶,內(nèi)部使用的是Orchestrator言秸,其語法為:

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

name 為任務(wù)名

deps 是當(dāng)前定義的任務(wù)需要依賴的其他任務(wù),為一個數(shù)組迎捺。當(dāng)前定義的任務(wù)會在所有依賴的任務(wù)執(zhí)行完畢后才開始執(zhí)行井仰。如果沒有依賴,則可省略這個參數(shù)

fn 為任務(wù)函數(shù)破加,我們把任務(wù)要執(zhí)行的代碼都寫在里面俱恶。該參數(shù)也是可選的。

gulp.task('mytask', ['array', 'of', 'task', 'names'], function() { //定義一個有依賴的任務(wù)

? ? // Do something

});

gulp.task()這個API沒什么好講的范舀,但需要知道執(zhí)行多個任務(wù)時(shí)怎么來控制任務(wù)執(zhí)行的順序合是。

gulp中執(zhí)行多個任務(wù),可以通過任務(wù)依賴來實(shí)現(xiàn)锭环。例如我想要執(zhí)行one,two,three這三個任務(wù)聪全,那我們就可以定義一個空的任務(wù),然后把那三個任務(wù)當(dāng)做這個空的任務(wù)的依賴就行了:

//只要執(zhí)行default任務(wù)辅辩,就相當(dāng)于把one,two,three這三個任務(wù)執(zhí)行了

gulp.task('default',['one','two','three']);

如果任務(wù)相互之間沒有依賴难礼,任務(wù)會按你書寫的順序來執(zhí)行,如果有依賴的話則會先執(zhí)行依賴的任務(wù)玫锋。

但是如果某個任務(wù)所依賴的任務(wù)是異步的蛾茉,就要注意了,gulp并不會等待那個所依賴的異步任務(wù)完成撩鹿,而是會接著執(zhí)行后續(xù)的任務(wù)谦炬。例如:

gulp.task('one',function(){

? ? //one是一個異步執(zhí)行的任務(wù)

? ? setTimeout(function(){

? ? ? ? console.log('one is done')

? ? },5000);

});

//two任務(wù)雖然依賴于one任務(wù),但并不會等到one任務(wù)中的異步操作完成后再執(zhí)行

gulp.task('two',['one'],function(){

? ? ? console.log('two is done');

});

上面的例子中我們執(zhí)行two任務(wù)時(shí),會先執(zhí)行one任務(wù)节沦,但不會去等待one任務(wù)中的異步操作完成后再執(zhí)行two任務(wù)键思,而是緊接著執(zhí)行two任務(wù)。所以two任務(wù)會在one任務(wù)中的異步操作完成之前就執(zhí)行了甫贯。

那如果我們想等待異步任務(wù)中的異步操作完成后再執(zhí)行后續(xù)的任務(wù)吼鳞,該怎么做呢?

有三種方法可以實(shí)現(xiàn):

第一:在異步操作完成后執(zhí)行一個回調(diào)函數(shù)來通知gulp這個異步任務(wù)已經(jīng)完成,這個回調(diào)函數(shù)就是任務(wù)函數(shù)的第一個參數(shù)叫搁。

gulp.task('one',function(cb){ //cb為任務(wù)函數(shù)提供的回調(diào)赔桌,用來通知任務(wù)已經(jīng)完成

? ? //one是一個異步執(zhí)行的任務(wù)

? ? setTimeout(function(){

? ? ? ? ? console.log('one is done');

? ? ? ? ? cb();? //執(zhí)行回調(diào),表示這個異步任務(wù)已經(jīng)完成

? ? },5000);

});

//這時(shí)two任務(wù)會在one任務(wù)中的異步操作完成后再執(zhí)行

gulp.task('two',['one'],function(){

? ? ? console.log('two is done');

});

第二:定義任務(wù)時(shí)返回一個流對象常熙。適用于任務(wù)就是操作gulp.src獲取到的流的情況纬乍。

gulp.task('one',function(cb){

? ? ? var stream = gulp.src('client/**/*.js')

? ? ? .pipe(dosomething()) //dosomething()中有某些異步操作

? ? .pipe(gulp.dest('build'));

? ? ? return stream;

});

gulp.task('two',['one'],function(){

? console.log('two is done');

});

第三:返回一個promise對象碱茁,例如

var Q = require('q'); //一個著名的異步處理的庫 https://github.com/kriskowal/q

gulp.task('one',function(cb){

? ? ? var deferred = Q.defer();

? ? ? // 做一些異步操作

? ? ? setTimeout(function() {

? ? ? ? ? deferred.resolve();

? ? ? }, 5000);

? ? ? return deferred.promise;

});

gulp.task('two',['one'],function(){

? ? ? console.log('two is done');

});

gulp.task()就這些了裸卫,主要是要知道當(dāng)依賴是異步任務(wù)時(shí)的處理。

3.4 gulp.watch()

gulp.watch()用來監(jiān)視文件的變化纽竣,當(dāng)文件發(fā)生變化后墓贿,我們可以利用它來執(zhí)行相應(yīng)的任務(wù)茧泪,例如文件壓縮等。其語法為

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

glob 為要監(jiān)視的文件匹配模式聋袋,規(guī)則和用法與gulp.src()方法中的glob相同队伟。

opts 為一個可選的配置對象,通常不需要用到

tasks 為文件變化后要執(zhí)行的任務(wù)幽勒,為一個數(shù)組

gulp.task('uglify',function(){

? //do something

});

gulp.task('reload',function(){

? //do something

});

gulp.watch('js/**/*.js', ['uglify','reload']);

gulp.watch()還有另外一種使用方式:

gulp.watch(glob[, opts, cb])

glob和opts參數(shù)與第一種用法相同

cb參數(shù)為一個函數(shù)嗜侮。每當(dāng)監(jiān)視的文件發(fā)生變化時(shí),就會調(diào)用這個函數(shù),并且會給它傳入一個對象啥容,該對象包含了文件變化的一些信息锈颗,type屬性為變化的類型,可以是added,changed,deleted咪惠;path屬性為發(fā)生變化的文件的路徑

gulp.watch('js/**/*.js', function(event){

? ? console.log(event.type); //變化類型 added為新增,deleted為刪除击吱,changed為改變

console.log(event.path); //變化的文件的路徑

});

4、一些常用的gulp插件

gulp的插件數(shù)量雖然沒有g(shù)runt那么多遥昧,但也可以說是應(yīng)有盡有了覆醇,下面列舉一些常用的插件。

4.1 自動加載插件

使用gulp-load-plugins

安裝:npm install --save-dev gulp-load-plugins

要使用gulp的插件炭臭,首先得用require來把插件加載進(jìn)來永脓,如果我們要使用的插件非常多,那我們的gulpfile.js文件開頭可能就會是這個樣子的:

var gulp = require('gulp'),

? ? //一些gulp插件,abcd這些命名只是用來舉個例子

? ? a = require('gulp-a'),

b = require('gulp-b'),

c = require('gulp-c'),

d = require('gulp-d'),

e = require('gulp-e'),

f = require('gulp-f'),

g = require('gulp-g'),

//更多的插件...

z = require('gulp-z');

雖然這沒什么問題鞋仍,但會使我們的gulpfile.js文件變得很冗長憨奸,看上去不那么舒服。gulp-load-plugins插件正是用來解決這個問題凿试。

gulp-load-plugins這個插件能自動幫你加載package.json文件里的gulp插件排宰。例如假設(shè)你的package.json文件里的依賴是這樣的:

{

? "devDependencies": {

? ? "gulp": "~3.6.0",

? ? "gulp-rename": "~1.2.0",

? ? "gulp-ruby-sass": "~0.4.3",

? ? "gulp-load-plugins": "~0.5.1"

? }

}

然后我們可以在gulpfile.js中使用gulp-load-plugins來幫我們加載插件:

var gulp = require('gulp');

//加載gulp-load-plugins插件,并馬上運(yùn)行它

var plugins = require('gulp-load-plugins')();

然后我們要使用gulp-rename和gulp-ruby-sass這兩個插件的時(shí)候那婉,就可以使用plugins.rename和plugins.rubySass來代替了,也就是原始插件名去掉gulp-前綴板甘,之后再轉(zhuǎn)換為駝峰命名。

實(shí)質(zhì)上gulp-load-plugins是為我們做了如下的轉(zhuǎn)換

plugins.rename = require('gulp-rename');

plugins.rubySass = require('gulp-ruby-sass');

gulp-load-plugins并不會一開始就加載所有package.json里的gulp插件详炬,而是在我們需要用到某個插件的時(shí)候盐类,才去加載那個插件。

最后要提醒的一點(diǎn)是呛谜,因?yàn)間ulp-load-plugins是通過你的package.json文件來加載插件的在跳,所以必須要保證你需要自動加載的插件已經(jīng)寫入到了package.json文件里,并且這些插件都是已經(jīng)安裝好了的隐岛。

4.2 重命名

使用gulp-rename

安裝:npm install --save-dev gulp-rename

用來重命名文件流中的文件猫妙。用gulp.dest()方法寫入文件時(shí),文件名使用的是文件流中的文件名聚凹,如果要想改變文件名割坠,那可以在之前用gulp-rename插件來改變文件流中的文件名齐帚。

var gulp = require('gulp'),

? ? rename = require('gulp-rename'),

? ? uglify = require("gulp-uglify");

gulp.task('rename', function () {

? ? gulp.src('js/jquery.js')

? ? .pipe(uglify())? //壓縮

? ? .pipe(rename('jquery.min.js')) //會將? ? ? jquery.js重命名為jquery.min.js

? ? .pipe(gulp.dest('js'));

//關(guān)于gulp-rename的更多強(qiáng)大的用法請參考https://www.npmjs.com/package/gulp-rename

});

4.3 js文件壓縮

使用gulp-uglify

安裝:npm install --save-dev gulp-uglify

用來壓縮js文件,使用的是uglify引擎

var gulp = require('gulp'),

? ? uglify = require("gulp-uglify");

gulp.task('minify-js', function () {

? ? ? gulp.src('js/*.js') // 要壓縮的js文件

? ? ? .pipe(uglify())? //使用uglify進(jìn)行壓縮,更多配置請參考:

? ? ? .pipe(gulp.dest('dist/js')); //壓縮后的路徑

});

4.4 css文件壓縮

使用gulp-minify-css

安裝:npm install --save-dev gulp-minify-css

要壓縮css文件時(shí)可以使用該插件

var gulp = require('gulp'),

? ? minifyCss = require("gulp-minify-css");

gulp.task('minify-css', function () {

? ? ? gulp.src('css/*.css') // 要壓縮的css文件

? ? .pipe(minifyCss()) //壓縮css

? ? .pipe(gulp.dest('dist/css'));

});

4.5 html文件壓縮

使用gulp-minify-html

安裝:npm install --save-dev gulp-minify-html

用來壓縮html文件

var gulp = require('gulp'),

? ? minifyHtml = require("gulp-minify-html");

gulp.task('minify-html', function () {

? ? ? gulp.src('html/*.html') // 要壓縮的html文件

? ? .pipe(minifyHtml()) //壓縮

? ? .pipe(gulp.dest('dist/html'));

});

4.6 js代碼檢查

使用gulp-jshint

安裝:npm install --save-dev gulp-jshint

用來檢查js代碼

var gulp = require('gulp'),

? ? jshint = require("gulp-jshint");

gulp.task('jsLint', function () {

? ? gulp.src('js/*.js')

? ? .pipe(jshint())

? ? .pipe(jshint.reporter()); // 輸出檢查結(jié)果

});

4.7 文件合并

使用gulp-concat

安裝:npm install --save-dev gulp-concat

用來把多個文件合并為一個文件,我們可以用它來合并js或css文件等彼哼,這樣就能減少頁面的http請求數(shù)了

var gulp = require('gulp'),

? ? concat = require("gulp-concat");

gulp.task('concat', function () {

? ? gulp.src('js/*.js')? //要合并的文件

? ? .pipe(concat('all.js'))? // 合并匹配到的js文件并命名為 "all.js"

? ? .pipe(gulp.dest('dist/js'));

});

4.8 less和sass的編譯

less使用gulp-less,安裝:npm install --save-dev gulp-less

var gulp = require('gulp'),

? ? less = require("gulp-less");

gulp.task('compile-less', function () {

? ? ? gulp.src('less/*.less')

? ? ? .pipe(less())

? ? ? .pipe(gulp.dest('dist/css'));

});

sass使用gulp-sass,安裝:npm install --save-dev gulp-sass

var gulp = require('gulp'),

? ? sass = require("gulp-sass");

gulp.task('compile-sass', function () {

? ? ? gulp.src('sass/*.sass')

? ? ? .pipe(sass())

? ? ? .pipe(gulp.dest('dist/css'));

});

4.9 圖片壓縮

可以使用gulp-imagemin插件來壓縮jpg对妄、png、gif等圖片敢朱。

安裝:npm install --save-dev gulp-imagemin

var gulp = require('gulp');

var imagemin = require('gulp-imagemin');

var pngquant = require('imagemin-pngquant'); //png圖片壓縮插件

gulp.task('default', function () {

? ? return gulp.src('src/images/*')

? ? .pipe(imagemin({

? ? ? ? progressive: true,

? ? ? ? use: [pngquant()] //使用pngquant來壓縮png圖片

? ? }))

? ? .pipe(gulp.dest('dist'));

});

gulp-imagemin的使用比較復(fù)雜一點(diǎn)剪菱,而且它本身也有很多插件,建議去它的項(xiàng)目主頁看看文檔

4.10 自動刷新

使用gulp-livereload插件拴签,安裝:npm install --save-dev gulp-livereload琅豆。

當(dāng)代碼變化時(shí),它可以幫我們自動刷新頁面

該插件最好配合谷歌瀏覽器來使用篓吁,且要安裝livereload chrome extension擴(kuò)展插件,不能下載的請自行FQ茫因。

var gulp = require('gulp'),

? ? less = require('gulp-less'),

? ? livereload = require('gulp-livereload');

gulp.task('less', function() {

? ? gulp.src('less/*.less')

? ? .pipe(less())

? ? .pipe(gulp.dest('css'))

? ? .pipe(livereload());

});

gulp.task('watch', function() {

? ? ? livereload.listen(); //要在這里調(diào)用listen()方法

? ? ? gulp.watch('less/*.less', ['less']);

});

如對gulp還有什么不明白之處,或者本文有什么遺漏或錯誤杖剪,歡迎一起交流和探討~

? ?

? ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冻押,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子盛嘿,更是在濱河造成了極大的恐慌洛巢,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件次兆,死亡現(xiàn)場離奇詭異稿茉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)芥炭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門漓库,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人园蝠,你說我怎么就攤上這事渺蒿。” “怎么了彪薛?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵茂装,是天一觀的道長。 經(jīng)常有香客問我善延,道長少态,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任易遣,我火速辦了婚禮彼妻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘训挡。我一直安慰自己澳骤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布澜薄。 她就那樣靜靜地躺著为肮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肤京。 梳的紋絲不亂的頭發(fā)上颊艳,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機(jī)與錄音忘分,去河邊找鬼棋枕。 笑死,一個胖子當(dāng)著我的面吹牛妒峦,可吹牛的內(nèi)容都是我干的重斑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼肯骇,長吁一口氣:“原來是場噩夢啊……” “哼窥浪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起笛丙,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤漾脂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后胚鸯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骨稿,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年姜钳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坦冠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡哥桥,死狀恐怖蓝牲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泰讽,我是刑警寧澤例衍,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站已卸,受9級特大地震影響佛玄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜累澡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一梦抢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧愧哟,春花似錦奥吩、人聲如沸哼蛆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腮介。三九已至,卻和暖如春端衰,著一層夾襖步出監(jiān)牢的瞬間叠洗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工旅东, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留灭抑,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓抵代,卻偏偏與公主長得像腾节,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子荤牍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

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

  • gulpjs是一個前端構(gòu)建工具禀倔,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù)参淫,API也非常簡單救湖,學(xué)...
    小裁縫sun閱讀 929評論 0 3
  • gulpjs是一個前端構(gòu)建工具,與gruntjs相比涎才,gulpjs無需寫一大堆繁雜的配置參數(shù)鞋既,API也非常簡單,學(xué)...
    依依玖玥閱讀 3,155評論 7 55
  • gulpjs是一個前端構(gòu)建工具耍铜,與gruntjs相比邑闺,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單棕兼,學(xué)...
    build1024閱讀 529評論 0 0
  • 1陡舅、gulp的安裝 首先確保你已經(jīng)正確安裝了nodejs環(huán)境。然后以全局方式安裝gulp: npm install...
    F_imok閱讀 2,378評論 1 11
  • 在現(xiàn)在的前端開發(fā)中伴挚,前后端分離靶衍、模塊化開發(fā)、版本控制茎芋、文件合并與壓縮颅眶、mock數(shù)據(jù)等等一些原本后端的思想開始...
    Charlot閱讀 5,443評論 1 32