gulp使用以及按照方式

1、gulp的安裝

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

npm install -g gulp

全局安裝gulp后,還需要在每個(gè)要使用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é)這個(gè)問題,只需要知道通常我們是要這樣做就行了。

2、開始使用gulp

2.1 建立gulpfile.js文件

就像gruntjs需要一個(gè)Gruntfile.js文件一樣,gulp也需要一個(gè)文件作為它的主文件,在gulp中這個(gè)文件叫做gulpfile.js。新建一個(gè)文件名為gulpfile.js的文件,然后放到你的項(xiàng)目目錄中。之后要做的事情就是在gulpfile.js文件中定義我們的任務(wù)了。下面是一個(gè)最簡單的gulpfile.js文件內(nèi)容示例,它定義了一個(gè)默認(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平臺(tái)請(qǐng)使用cmd或者Power Shell等工具),然后在命令行中執(zhí)行g(shù)ulp命令就行了,gulp后面可以加上要執(zhí)行的任務(wù)名,例如gulp task1,如果沒有指定任務(wù)名,則會(huì)執(zhí)行任務(wù)名為default的默認(rèn)任務(wù)。

gulp的API介紹

使用gulp,僅需知道4個(gè)API即可:

gulp.task(),gulp.src(),gulp.dest(),gulp.watch()

所以很容易就能掌握,但有幾個(gè)地方需理解透徹才行,我會(huì)在下面一一說明。為了避免出現(xiàn)理解偏差,建議先看一遍官方文檔。

3.1 gulp.src()

在介紹這個(gè)API之前我們首先來說一下Grunt.js和Gulp.js工作方式的一個(gè)區(qū)別。Grunt主要是以文件為媒介來運(yùn)行它的工作流的,比如在Grunt中執(zhí)行完一項(xiàng)任務(wù)后,會(huì)把結(jié)果寫入到一個(gè)臨時(shí)文件中,然后可以在這個(gè)臨時(shí)文件內(nèi)容的基礎(chǔ)上執(zhí)行其它任務(wù),執(zhí)行完成后又把結(jié)果寫入到臨時(shí)文件中,然后又以這個(gè)為基礎(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快的一個(gè)原因。再回到正題上來,gulp.src()方法正是用來獲取流的,但要注意這個(gè)流里的內(nèi)容不是原始的文件流,而是一個(gè)虛擬文件對(duì)象流(Vinyl files),這個(gè)虛擬文件對(duì)象中存儲(chǔ)著原始文件的路徑、文件名、內(nèi)容等信息,這個(gè)我們暫時(shí)不用去深入理解,你只需簡單的理解可以用這個(gè)方法來讀取你需要操作的文件就行了。其語法為:

gulp.src(globs[, options])

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

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

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

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

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

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

?代表匹配文件路徑中的一個(gè)字符(不會(huì)匹配路徑分隔符)

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

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

//使用數(shù)組的方式來匹配多種文件gulp.src(['js/*.js','css/*.css','*.html'])

gulp.src([*.js,'!b*.js']) //匹配所有js文件,但排除掉以b開頭的js文件gulp.src(['!b*.js',*.js]) //不會(huì)排除任何文件,因?yàn)榕懦J讲荒艹霈F(xiàn)在數(shù)組的第一個(gè)元素中

3.2 gulp.dest()

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

gulp.dest(path[,options])

path為寫入文件的路徑

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

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

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)的那部分路徑為 **/*.jsgulp.src('script/**/*.js')? ? .pipe(gulp.dest('dist')); //最后生成的文件路徑為 dist/**/*.js//如果 **/*.js 匹配到的文件為 jquery/jquery.js ,則生成的文件路徑為 dist/jquery/jquery.js

3.3 gulp.task()

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

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

name 為任務(wù)名

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

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

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

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

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

//只要執(zhí)行default任務(wù),就相當(dāng)于把one,two,three這三個(gè)任務(wù)執(zhí)行了gulp.task('default',['one','two','three']);

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

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

gulp.task('one',function(){? //one是一個(gè)異步執(zhí)行的任務(wù)? setTimeout(function(){? ? console.log('one is done')? },5000); });//two任務(wù)雖然依賴于one任務(wù),但并不會(huì)等到one任務(wù)中的異步操作完成后再執(zhí)行g(shù)ulp.task('two',['one'],function(){? console.log('two is done'); });

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

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

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

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

gulp.task('one',function(cb){ //cb為任務(wù)函數(shù)提供的回調(diào),用來通知任務(wù)已經(jīng)完成? //one是一個(gè)異步執(zhí)行的任務(wù)? setTimeout(function(){? ? console.log('one is done');? ? cb();? //執(zhí)行回調(diào),表示這個(gè)異步任務(wù)已經(jīng)完成? },5000); });//這時(shí)two任務(wù)會(huì)在one任務(wù)中的異步操作完成后再執(zhí)行g(shù)ulp.task('two',['one'],function(){? console.log('two is done'); });

第二:定義任務(wù)時(shí)返回一個(gè)流對(duì)象。適用于任務(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');

});

第三:返回一個(gè)promise對(duì)象,例如

var Q = require('q'); //一個(gè)著名的異步處理的庫 https://github.com/kriskowal/qgulp.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 為一個(gè)可選的配置對(duì)象,通常不需要用到

tasks 為文件變化后要執(zhí)行的任務(wù),為一個(gè)數(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ù)為一個(gè)函數(shù)。每當(dāng)監(jiān)視的文件發(fā)生變化時(shí),就會(huì)調(diào)用這個(gè)函數(shù),并且會(huì)給它傳入一個(gè)對(duì)象,該對(duì)象包含了文件變化的一些信息,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 自動(dòng)加載插件

使用gulp-load-plugins

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

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

var gulp = require('gulp'),? ? //一些gulp插件,abcd這些命名只是用來舉個(gè)例子

? ? 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');?

雖然這沒什么問題,但會(huì)使我們的gulpfile.js文件變得很冗長,看上去不那么舒服。gulp-load-plugins插件正是用來解決這個(gè)問題。

gulp-load-plugins這個(gè)插件能自動(dòng)幫你加載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這兩個(gè)插件的時(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并不會(huì)一開始就加載所有package.json里的gulp插件,而是在我們需要用到某個(gè)插件的時(shí)候,才去加載那個(gè)插件。

最后要提醒的一點(diǎn)是,因?yàn)間ulp-load-plugins是通過你的package.json文件來加載插件的,所以必須要保證你需要自動(dòng)加載的插件已經(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')) //會(huì)將jquery.js重命名為jquery.min.js

? ? .pipe(gulp.dest('js'));? ? //關(guān)于gulp-rename的更多強(qiáng)大的用法請(qǐ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)行壓縮,更多配置請(qǐng)參考:

? ? .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

用來把多個(gè)文件合并為一個(gè)文件,我們可以用它來合并js或css文件等,這樣就能減少頁面的http請(qǐng)求數(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 自動(dòng)刷新

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

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

該插件最好配合谷歌瀏覽器來使用,且要安裝livereload chrome extension擴(kuò)展插件,不能下載的請(qǐng)自行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']);

});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • gulpjs是一個(gè)前端構(gòu)建工具,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單,學(xué)...
    依依玖玥閱讀 3,304評(píng)論 7 55
  • gulpjs是一個(gè)前端構(gòu)建工具,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單,學(xué)...
    井皮皮閱讀 1,401評(píng)論 0 10
  • gulpjs是一個(gè)前端構(gòu)建工具,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單,學(xué)...
    小裁縫sun閱讀 1,030評(píng)論 0 3
  • gulpjs是一個(gè)前端構(gòu)建工具,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單,學(xué)...
    build1024閱讀 585評(píng)論 0 0
  • 安裝Gulp首先需要安裝Node.js,并在控制臺(tái)輸入$ npm install gulp -gMac端需要寫成$...
    LaBaby_閱讀 1,023評(píng)論 0 1

友情鏈接更多精彩內(nèi)容