前端構建工具gulp超詳細配置, 使用教程(圖文)

流程

1. 輸入命令(可使用git bash或者命令控制檯cmd) npm install -g gulp

  • 安裝全局gulp命令

2. 建立一個項目文件夾, 當前項目文件夾下輸入命令npm init

這裏寫圖片描述
配置package.json文件, 這一部分看狀況本身決定是否填, 不想填也能夠, 直接按回車
這裏寫圖片描述javascript

當前項目文件夾下輸入命令npm install gulp --save-dev

全局安裝gulp後,還須要在每一個要使用gulp的項目中都單獨安裝一次css

開始使用gulp

其實, gulp的使用比webpack要簡單不少.html

配置gulpflie.js文件

在當前項目文件下建立文件名爲gulpfile.js文件, 做爲該項目配置文件. java



//gulpfile.js var gulp = require('gulp'); gulp.task('default',function(){ console.log('hello world'); });

其實在項目文件夾下輸入命令gulp時, 就是觸發這個default任務, 所以, 咱們定義多個自定義事件, 這樣在輸入gulp時, 就能夠直接將咱們寫的命令也一塊兒觸發.jquery

gulp API

gulp.src(globs[, options])

globs參數是文件匹配模式(相似正則表達式),用來匹配文件路徑(包括文件名),固然這裏也能夠直接指定某個具體的文件路徑。當有多個匹配模式時,該參數能夠爲一個數組。
options爲可選參數。一般狀況下咱們不須要用到。webpack

下面咱們重點說說Gulp用到的glob的匹配規則以及一些文件匹配技巧。

名稱 說明
* 匹配文件路徑中的0個或多個字符,但不會匹配路徑分隔符,除非路徑分隔符出如今末尾
** 匹配路徑中的0個或多個目錄及其子目錄,須要單獨出現,即它左右不能有其餘東西了。若是出如今末尾,也能匹配文件。
? 匹配文件路徑中的一個字符(不會匹配路徑分隔符)
[…] 匹配方括號中出現的字符中的任意一個,當方括號中第一個字符爲^或!時,則表示不匹配方括號中出現的其餘字符中的任意一個,相似js正則表達式中的用法
!(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)

例子: git



當有多種匹配模式時可使用數組//轉換html文件 gulp.task('html', function(){ gulp.src('./src/index.html') .pipe(connect.reload()) .pipe(gulp.dest('./dist'));//寫入命令 });


使用數組的方式還有一個好處就是能夠很方便的使用排除模式,在數組中的單個匹配模式前加上!便是排除模式,它會在匹配的結果中排除這個匹配,要注意一點的是不能在數組中的第一個元素中使用排除模式//使用數組的方式來匹配多種文件 gulp.src(['js/*.js','css/*.css','*.html'])


gulp.src([*.js,'!b*.js']) //匹配全部js文件,但排除掉以b開頭的js文件 gulp.src(['!b*.js',*.js]) //不會排除任何文件,由於排除模式不能出如今

數組的第一個元素中
此外,還可使用展開模式。展開模式以花括號做爲定界符,根據它裏面的內容,會展開爲多個模式,最後匹配的結果爲全部展開的模式相加起來獲得的結果。展開的例子以下:github

  • 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.dest(path[,options])

gulp.dest()方法是用來寫文件的
path爲寫入文件的路徑
options爲一個可選的參數對象,一般咱們不須要用到web

要想使用好gulp.dest()這個方法,就要理解給它傳入的路徑參數與最終生成的文件的關係。正則表達式

gulp的使用流程通常是這樣子的:首先經過gulp.src()方法獲取到咱們想要處理的文件流,而後把文件流經過pipe方法導入到gulp的插件中,最後把通過插件處理後的流再經過pipe方法導入到gulp.dest()中,gulp.dest()方法則把流中的內容寫入到文件中,這裏首先須要弄清楚的一點是,咱們給gulp.dest()傳入的路徑參數,只能用來指定要生成的文件的目錄,而不能指定生成文件的文件名,它生成文件的文件名使用的是導入到它的文件流自身的文件名,因此生成的文件名是由導入到它的文件流決定的,即便咱們給它傳入一個帶有文件名的路徑參數,而後它也會把這個文件名當作是目錄名,例如:



下面說說生成的文件路徑與咱們給方法傳入的路徑參數之間的關係。
生成的文件路徑是咱們傳入的path參數後面再加上中有通配符開始出現的那部分路徑。例如:var gulp = require('gulp'); gulp.src('script/jquery.js') .pipe(gulp.dest('dist/foo.js')); //最終生成的文件路徑爲 dist/foo.js/jquery.js,而不是dist/foo.js 要想改變文件名,可使用插件gulp-renamegulp.dest()gulp.dest(path)gulp.src()


再舉更多一點的例子

var gulp = reruire('gulp'); //有通配符開始出現的那部分路徑爲 **/*.js gulp.src('script/**/*.js') .pipe(gulp.dest('dist')); //最後生成的文件路徑爲 dist/**/*.js //若是 **/*.js 匹配到的文件爲 jquery/jquery.js ,則生成的文件路徑爲 dist/jquery/jquery.js


經過指定方法配置參數中的base屬性,咱們能夠更靈活的來改變生成的文件路徑。
當咱們沒有在方法中配置base屬性時,base的默認值爲通配符開始出現以前那部分路徑,例如:

gulp.src('script/avalon/avalon.js') //沒有通配符出現的狀況 .pipe(gulp.dest('dist')); //最後生成的文件路徑爲 dist/avalon.js //有通配符開始出現的那部分路徑爲 **/underscore.js gulp.src('script/**/underscore.js') //假設匹配到的文件爲script/util/underscore.js .pipe(gulp.dest('dist')); //則最後生成的文件路徑爲 dist/util/underscore.js gulp.src('script/*') //有通配符出現的那部分路徑爲 * //假設匹配到的文件爲script/zepto.js .pipe(gulp.dest('dist')); //則最後生成的文件路徑爲 dist/zepto.jsgulp.src()gulp.dest()gulp.src()


上面咱們說的所生成的文件路徑的規則,其實也能夠理解成,用咱們給傳入的路徑替換掉gulp.src()中的base路徑,最終獲得生成文件的路徑。gulp.src('app/src/**/*.css') //此時base的值爲 app/srcgulp.dest()gulp.dest()


因此改變base路徑後,gulp.dest()生成的文件路徑也會改變gulp.src('app/src/**/*.css') //此時base的值爲app/src,也就是說它的base路徑爲app/src //設該模式匹配到了文件 app/src/css/normal.css .pipe(gulp.dest('dist')) //用dist替換掉base路徑,最終獲得 dist/css/normal.css


gulp.src(script/lib/*.js) //沒有配置base參數,此時默認的base路徑爲script/lib //假設匹配到的文件爲script/lib/jquery.js .pipe(gulp.dest('build')) //生成的文件路徑爲 build/jquery.js gulp.src(script/lib/*.js, {base:'script'}) //配置了base參數,此時base路徑爲script //假設匹配到的文件爲script/lib/jquery.js .pipe(gulp.dest('build')) //此時生成的文件路徑爲 build/lib/jquery.js

gulp.dest()把文件流寫入文件後,文件流仍然能夠繼續使用。


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

gulp.task方法用來定義任務,內部使用的是Orchestrator

name 爲任務名
deps 是當前定義的任務須要依賴的其餘任務,爲一個數組。當前定義的任務會在全部依賴的任務執行完畢後纔開始執行。若是沒有依賴,則可省略這個參數
fn 爲任務函數,咱們把任務要執行的代碼都寫在裏面。該參數也是可選的。



這個API沒什麼好講的,但須要知道執行多個任務時怎麼來控制任務執行的順序。
gulp中執行多個任務,能夠經過任務依賴來實現。例如我想要執行,,這三個任務,那咱們就能夠定義一個空的任務,而後把那三個任務當作這個空的任務的依賴就好了:gulp.task('mytask', ['array', 'of', 'task', 'names'], function() { //定義一個有依賴的任務 // Do something });gulp.task()onetwothree


若是任務相互之間沒有依賴,任務會按你書寫的順序來執行,若是有依賴的話則會先執行依賴的任務。
可是若是某個任務所依賴的任務是異步的,就要注意了,gulp並不會等待那個所依賴的異步任務完成,而是會接着執行後續的任務。例如://只要執行default任務,就至關於把one,two,three這三個任務執行了 gulp.task('default',['one','two','three']);


gulp.task('one',function(){ //one是一個異步執行的任務 setTimeout(function(){ console.log('one is done') },5000); }); //two任務雖然依賴於one任務,但並不會等到one任務中的異步操做完成後再執行 gulp.task('two',['one'],function(){ console.log('two is done'); });

上面的例子中咱們執行two任務時,會先執行one任務,但不會去等待one任務中的異步操做完成後再執行two任務,而是緊接着執行two任務。因此two任務會在one任務中的異步操做完成以前就執行了。

那若是咱們想等待異步任務中的異步操做完成後再執行後續的任務,該怎麼作呢?
有三種方法能夠實現:
第一:在異步操做完成後執行一個回調函數來通知gulp這個異步任務已經完成,這個回調函數就是任務函數的第一個參數。



第二:定義任務時返回一個流對象。適用於任務就是操做gulp.src獲取到的流的狀況。gulp.task('one',function(cb){ //cb爲任務函數提供的回調,用來通知任務已經完成 //one是一個異步執行的任務 setTimeout(function(){ console.log('one is done'); cb(); //執行回調,表示這個異步任務已經完成 },5000); }); //這時two任務會在one任務中的異步操做完成後再執行 gulp.task('two',['one'],function(){ console.log('two is done'); });


第三:返回一個promise對象,例如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'); });


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()就這些了,主要是要知道當依賴是異步任務時的處理。


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

gulp.watch()用來監視文件的變化,當文件發生變化後,咱們能夠利用它來執行相應的任務,例如文件壓縮等。
glob 爲要監視的文件匹配模式,規則和用法與gulp.src()方法中的glob相同。
opts 爲一個可選的配置對象,一般不須要用到
tasks 爲文件變化後要執行的任務,爲一個數組



glob和opts參數與第一種用法相同
cb參數爲一個函數。每當監視的文件發生變化時,就會調用這個函數,而且會給它傳入一個對象,該對象包含了文件變化的一些信息,type屬性爲變化的類型,能夠是added,changed,deleted;path屬性爲發生變化的文件的路徑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])


gulp.watch('js/**/*.js', function(event){ console.log(event.type); //變化類型 added爲新增,deleted爲刪除,changed爲改變 console.log(event.path); //變化的文件的路徑 });

一些經常使用的gulp插件

1. 自動加載插件

使用:gulp-load-plugins
安裝:npm install --save-dev gulp-load-plugins
要使用gulp的插件,首先得用require來把插件加載進來,若是咱們要使用的插件很是多,那咱們的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.jsgulp-load-pluginsgulp-load-pluginspackage.jsongulppackage.json


而後咱們能夠在中使用來幫咱們加載插件:{ "devDependencies": { "gulp": "~3.6.0", "gulp-rename": "~1.2.0", "gulp-ruby-sass": "~0.4.3", "gulp-load-plugins": "~0.5.1" } }gulpfile.jsgulp-load-plugins


而後咱們要使用和這兩個插件的時候,就可使用和來代替了,也就是原始插件名去掉gulp-前綴,以後再轉換爲駝峯命名。
實質上是爲咱們作了以下的轉換var gulp = require('gulp'); //加載gulp-load-plugins插件,並立刻運行它 var plugins = require('gulp-load-plugins')();gulp-renamegulp-ruby-sassplugins.renameplugins.rubySassgulp-load-plugins


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

gulp-load-plugins並不會一開始就加載全部package.json裏的gulp插件,而是在咱們須要用到某個插件的時候,纔去加載那個插件。
最後要提醒的一點是,由於gulp-load-plugins是經過你的k文件來加載插件的,因此必需要保證你須要自動加載的插件已經寫入到了package.json文件裏,而且這些插件都是已經安裝好了的。

2. 重命名

使用:gulp-rename
安裝:npm install --save-dev gulp-rename
用來重命名文件流中的文件。用gulp.dest()方法寫入文件時,文件名使用的是文件流中的文件名,若是要想改變文件名,那能夠在以前用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')); //關於gulp-rename的更多強大的用法請參考https://www.npmjs.com/package/gulp-rename });

3. js文件壓縮

使用 : gulp-uglify
安裝:npm install --save-dev gulp-uglify
用來壓縮js文件,使用的是uglify引擎



var gulp = require('gulp'); var uglify = require('gulp-uglify'); var pump = require('pump'); gulp.task('compress', function (cb) { pump([ gulp.src('lib/*.js'), uglify(), gulp.dest('dist') ], cb ); });

4. css文件壓縮

使用 : gulp-clean-css
安裝:npm install gulp-clean-css --save-dev
要壓縮css文件時可使用該插件



var gulp = require('gulp'); var cleanCSS = require('gulp-clean-css'); gulp.task('minify-css', function() { return gulp.src('styles/*.css') .pipe(cleanCSS({compatibility: 'ie8'})) .pipe(gulp.dest('dist')); });

5. html文件壓縮

使用 : gulp-htmlmin
安裝:npm i gulp-htmlmin --save-dev
用來壓縮html文件



var gulp = require('gulp'); var htmlmin = require('gulp-htmlmin'); gulp.task('minify', function() { return gulp.src('src/*.html') .pipe(htmlmin({collapseWhitespace: true})) .pipe(gulp.dest('dist')); });

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()); // 輸出檢查結果 });

7. 文件合併

使用 : gulp-concat
安裝:npm install --save-dev gulp-concat
用來把多個文件合併爲一個文件,咱們能夠用它來合併js或css文件等,這樣就能減小頁面的http請求數了



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

8. less和sass的編譯

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



sass使用gulp-sass,安裝:

var gulp = require('gulp'), less = require("gulp-less"); gulp.task('compile-less', function () { gulp.src('less/*.less') .pipe(less()) .pipe(gulp.dest('dist/css')); });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')); });

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的使用比較複雜一點,並且它自己也有不少插件,建議去它的項目主頁看看文檔

10. 自動刷新

使用gulp-livereload插件,安裝:npm install --save-dev gulp-livereload。
當代碼變化時,它能夠幫咱們自動刷新頁面
該插件最好配合谷歌瀏覽器來使用,且要安裝livereload chrome extension擴展插件,不能下載的請自行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(); //要在這裏調用listen()方法 gulp.watch('less/*.less', ['less']); });

11. 服務器

使用 : gulp-connect插件,
安裝 : npm install --save-dev gulp-connect
Gulp plugin to run a webserver (with LiveReload), 開服務器,並集成了LiveReload(自動刷新), 下載這個插件上面的LiverReload插件就不用再下載了.

var gulp = require('gulp'), connect = require('gulp-connect'); gulp.task('connect', function() { connect.server({ root: 'app', livereload: true }); });
相關文章
相關標籤/搜索