gulp簡介
gulp,是基于nodejs的前端自動化構(gòu)建工具,用于壓縮項目文件,合并文件,部署等,簡言之,就是解放生產(chǎn)力,提高開發(fā)效率。
現(xiàn)如今的前端全正處于飛速發(fā)展期,各種號稱解放生產(chǎn)力的工具,框架噴涌而出,導(dǎo)致技術(shù)棧卻是處于不穩(wěn)定的狀態(tài),雖然技術(shù)層出不窮,但還是不要盲目的去推崇,還是結(jié)合項目本身找到合適的技術(shù)棧比較好。
現(xiàn)在大多數(shù)項目的技術(shù)棧中使用到的前端構(gòu)建打包工具都是webpack或者webpack+gulp結(jié)合使用,本系列將講解下gulp的使用。
使用前準(zhǔn)備
nodejs安裝
說明: gulp是基于nodejs運行的前端自動化構(gòu)建工具,所以必須要先安裝nodejs,可前往nodejs官網(wǎng)下載nodejs包安裝。使用命令行
說明:window系統(tǒng)下可通過window + r 輸入cmd回車啟動命令行界面,或者安裝git客戶端。
簡單介紹下幾個常用的命令
1.node -v:查看安裝的nodejs版本,出現(xiàn)版本號,說明剛剛已正確安裝nodejs
2.npm -v:查看npm的版本號
3.cd:定位到目錄,用法:cd + 路徑
4.dir:列出文件列表
5.cls:清空命令提示符窗口內(nèi)容npm介紹
說明:npm是nodejs的包管理器,用于node插件管理(包括安裝、卸載、管理依賴等)
1.安裝插件:通過命令行 npm install <name> [g] [--save-dev] 安裝
注: <name>,插件名稱,如:npm install gulp -g --save-dev。
[g],全局安裝插件,可以通過命令行在任何地方調(diào)用它,PS: 本地安裝將安裝在定位目錄的node_modules文件夾下,通過require()調(diào)用。
--save,將保存配置信息至package.json。
-dev,保存至package.json的devDependencies節(jié)點,不指定-dev將保存至dependencies節(jié)點。
2.卸載插件:通過命令行 npm uninstall <name> [-g] [--save-dev] 卸載
3.更新插件:通過命令行 npm update <name> [-g] [--save-dev] 更新cnpm的安裝
由于npm是從國外服務(wù)器下載插件,可能網(wǎng)絡(luò)方面會比較的慢,影響下載,因此我們需要通過代理的方式來解決這個問題。cnmp是一個淘寶代理鏡像,能夠代替npm下載需要的插件。
說明: 通過命令行 npm install cnpm -g --registry=https://registry.npm.taobao.org 安裝cnpm鏡像代理,安裝好后可通過命令行 cnpm -v查看是否安裝成功。
注: cnpm跟npm用法完全一致,只是在執(zhí)行命令時將npm改為cnpm(以下操作將以cnpm代替npm)。
gulp API
先來了解下gulp常用的一些API。
1. gulp.src()
需要處理的源文件路徑,參數(shù)可以是字符串,也可以是字符串?dāng)?shù)組,參數(shù)可以是通配符類型。比如,需要將項目下js文件夾下所有js文件做處理,就可以這樣寫:gulp.src("js/.js")*
2. gulp.dest()
指定處理完后文件的輸出路徑,參數(shù)類型為String or Function。
比如將項目下js文件夾下所有js文件處理完后,保存到同級的dist文件夾中,就可以這樣寫:gulp.dest("dist")
3. gulp.pipe()
該API可以鏈?zhǔn)秸{(diào)用,在輸出和輸入之間,可以用pipe指定任意的插件去處理你的文件。
4. gulp.task()
定制gulp任務(wù),參數(shù)類型可以是字符串也可以是數(shù)組,比如定義第一個gulp執(zhí)行任務(wù),就可以這樣寫:gulp.task("firstGulp",function(){})
5. gulp.watch()
用于監(jiān)聽文件變化,任務(wù)gulp執(zhí)行
具體的API參數(shù)詳解,請參考這兩篇關(guān)于gulp API的文章
http://www.gulpjs.com.cn/docs/api/
http://www.ydcss.com/archives/424
使用gulp壓縮打包js文件
-
安裝gulp
首先需要在全局下安裝gulp,通過命令行 cnpm install gulp -g全局安裝gulp。
新建一個gulp文件夾,目錄結(jié)構(gòu)如下,
---gulp源文件夾
---script文件夾
---a.js
---package.json文件
---gulpfile.js文件
在gulp文件夾根目錄下,通過命令行 cnpm install gulp --save-dev,把gulp插件安裝到本地項目的根目錄中,至于為什么已經(jīng)在全局安裝了gulp還要在本地項目目錄再安裝gulp,這是為了防止版本沖突。
在a.js中寫入一段代碼,這是需要壓縮的js文件
function gulpHello(){
alert("this is gulp firstDemo: hello world!");
}
接著,在項目的根目錄下創(chuàng)建一個名為gulpfile.js的文件,這個文件名是gulp固定的,不能修改的。在gulpfile.js中,寫入如下代碼:
//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模塊,用于壓縮js
var uglify = require("gulp-uglify");
//自定義任務(wù),firstGulp為自定義任務(wù)名
gulp.task("firstGulp",function(){
gulp.src("./script/a.js")
.pipe(uglify())
.pipe(gulp.dest("./dest"))
})
之后再通過命令行執(zhí)行該任務(wù),輸入gulp firstGulp命令行,敲擊回車,執(zhí)行結(jié)果如下圖

出現(xiàn)了報錯情況,原因是因為上面引入了壓縮js的gulp-uglify模塊沒有下載到本地,所以我們在引入模塊之前,得在本地安裝我們需要引入的模塊,且引入的模塊名與需要安裝的模塊名是一致的。
比如安裝gulp-uglify模塊,通過命令行 cnpm install gulp-uglify --save-dev 安裝即可。
再來執(zhí)行g(shù)ulp下任務(wù),會發(fā)現(xiàn),gulp文件夾中多了一個dist文件夾,里面的a.js文件就是我們壓縮過的js文件。

雖然這樣可以達到壓縮文件的效果了,但是有一點不足的地方就是每次文件修改后都要通過命令行來執(zhí)行任務(wù),這樣就并沒有體現(xiàn)出gulp的自動化這樣強大的功能。所以得完善gulpfile.js的代碼,使其自動化,一旦文件有所改動,就自動執(zhí)行g(shù)ulp任務(wù)。
這里就可以使用gulp.watch()的API了,來監(jiān)聽文件的改動,從而執(zhí)行相應(yīng)的任務(wù)。
gulpfile.js文件代碼修改如下:
//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模塊,用于壓縮js
var uglify = require("gulp-uglify");
//自定義任務(wù),firstGulp為自定義任務(wù)名
gulp.task("firstGulp",function(){
gulp.src("./script/a.js")
.pipe(uglify())
.pipe(gulp.dest("./dest"))
})
//新增一個auto的任務(wù)
gulp.task("auto",function(){
//watch()監(jiān)聽a.js文件的變動,如果變動,就執(zhí)行firstGulp任務(wù)
//如果監(jiān)聽script下所有文件,只需把第一個參數(shù)改成script/*.js
gulp.watch("./script/a.js",["firstGulp"]);
})
然后只需要執(zhí)行命令行 gulp auto 就可以實行自動化壓縮文件了,但是這樣還是有點不完善,就是gulp.watch方法監(jiān)聽到script文件夾中的某個js代碼發(fā)生改變時,gulp會將script下所有的js都壓縮一遍,極大地影響性能。
為了完善這一點,我們需要引入gulp-watch-path模塊,就可以達到修改了哪個文件就壓縮哪個文件的目的,而不是盲目壓縮。在script文件夾下新增b.js和c.js兩個js文件,隨便放入一些代碼,監(jiān)聽script文件夾下所有文件,那么如何使用gulp-watch-path模塊,代碼如下:
//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模塊,用于壓縮js
var uglify = require("gulp-uglify");
//引入gulp-watch-path模塊
var watchPath = require("gulp-watch-path");
//自定義任務(wù),firstGulp為自定義任務(wù)名
gulp.task("firstGulp",function(){
gulp.src("./script/a.js")
.pipe(uglify())
.pipe(gulp.dest("./dest"))
})
//新增一個auto的任務(wù)
gulp.task("auto",function(){
//watch()監(jiān)聽a.js文件的變動,如果變動,就執(zhí)行firstGulp任務(wù)
//如果監(jiān)聽script下所有文件,只需把第一個參數(shù)改成script/*.js
//gulp.watch("./script/a.js",["firstGulp"]);
gulp.watch("./script/*.js", function(event){
var paths = watchPath(event,"script","dist");
gulp.src(paths.srcPath)
.pipe(uglify())
//paths.distDir為目錄文件
.pipe(gulp.dest(paths.distDir));
})
})
然后再在項目中安裝gulp-watch-path模塊,執(zhí)行命令行 gulp auto,再修改a.js
function gulpHello(){
alert("this is gulp firstDemo: hello world!");
alert("do something...");
}
然后在dist文件夾下,可以看到壓縮后的a.js了,這樣就實現(xiàn)了自動化壓縮且不盲目壓縮的效果了。

但是每次執(zhí)行任務(wù)都需要輸入gulp+任務(wù)名才行,為了更加的簡潔完善,只需要輸入gulp敲擊回車就可以執(zhí)行任務(wù),那么完善gulpfile.js就這樣實現(xiàn):
//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模塊,用于壓縮js
var uglify = require("gulp-uglify");
//引入gulp-watch-path模塊
var watchPath = require("gulp-watch-path");
//自定義任務(wù),firstGulp為自定義任務(wù)名
gulp.task("firstGulp",function(){
gulp.src("./script/a.js")
.pipe(uglify())
.pipe(gulp.dest("./dest"))
})
//新增一個auto的任務(wù)
gulp.task("auto",function(){
//watch()監(jiān)聽a.js文件的變動,如果變動,就執(zhí)行firstGulp任務(wù)
//如果監(jiān)聽script下所有文件,只需把第一個參數(shù)改成script/*.js
//gulp.watch("./script/a.js",["firstGulp"]);
gulp.watch("./script/*.js", function(event){
var paths = watchPath(event,"script","dist");
gulp.src(paths.srcPath)
.pipe(uglify())
//paths.distDir為目錄文件
.pipe(gulp.dest(paths.distDir));
})
})
//default為gulp默認任務(wù)
gulp.task("default",["auto"])
這樣就只需要輸入gulp敲擊回車就可以執(zhí)行任務(wù)了,這樣就更加完善了一步。
但是我們發(fā)現(xiàn),壓縮后的文件與源文件的文件名是一樣的,我們壓縮的源文件名為a.js,在dist文件夾下壓縮過后的文件名也是a.js。通常我們見到的被壓縮過的文件都是會帶有.min的后綴,為了完善這一效果,需要引入gulp-rename模塊,用于重命名壓縮后的文件。
gulpfile.js修改如下:
//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模塊,用于壓縮js
var uglify = require("gulp-uglify");
//引入gulp-watch-path模塊
var watchPath = require("gulp-watch-path");
//引入gulp-rename模塊,用于重命名壓縮后的文件
var rename = require("gulp-rename");
//自定義任務(wù),firstGulp為自定義任務(wù)名
gulp.task("firstGulp",function(){
gulp.src("./script/a.js")
.pipe(uglify())
.pipe(gulp.dest("./dest"))
})
//新增一個auto的任務(wù)
gulp.task("auto",function(){
//watch()監(jiān)聽a.js文件的變動,如果變動,就執(zhí)行firstGulp任務(wù)
//如果監(jiān)聽script下所有文件,只需把第一個參數(shù)改成script/*.js
//gulp.watch("./script/a.js",["firstGulp"]);
gulp.watch("./script/*.js", function(event){
var paths = watchPath(event,"script","dist");
gulp.src(paths.srcPath)
.pipe(uglify())
//給壓縮后的文件添加.min后綴
.pipe(rename({suffix: ".min"}))
//paths.distDir為目錄文件
.pipe(gulp.dest(paths.distDir));
})
})
//default為gulp默認任務(wù)
gulp.task("default",["auto"])
再來執(zhí)行下gulp,會發(fā)現(xiàn)壓縮后的文件名改變了

合并壓縮js文件
如果是在實際項目當(dāng)中,js文件的個數(shù)肯定是很多的,就算我們壓縮小了所以文件的體積,把100kb大小的文件壓縮成了3kb大小,但在頁面還是需要那么多的script標(biāo)簽來引用這些文件,script標(biāo)簽或者link標(biāo)簽過多的話是會影響頁面加載性能的。為了進一步優(yōu)化頁面的加載性能,我們需要把多個文件合并壓縮成一個文件,然后在頁面中引入這個壓縮后的文件即可,這樣就減少了引入標(biāo)簽的使用。當(dāng)然在合并壓縮的過程中還要考慮到模塊文件之間的依賴關(guān)系。
首先a.js,b.js,c.js文件代碼修改如下:
a.js
function gulpHello(s){
alert("this is gulp firstDemo: hello world!");
alert("do something...");
alert(s);
}
b.js
gulpHello("這是b.js傳入的參數(shù)");
function Person(name,age){
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name);
}
}
c.js
var ps = new Person("z3", 30);
ps.sayName();
可以明顯看出3個js文件中存在這依賴關(guān)系,b.js依賴于a.js,c.js依賴于b.js,那么我們需要引入gulp-concat模塊來合并文件,在本地項目中安裝該模塊,gulpfile.js代碼修改如下:
//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模塊,用于壓縮js
var uglify = require("gulp-uglify");
//引入gulp-watch-path模塊
var watchPath = require("gulp-watch-path");
//引入gulp-rename模塊,用于重命名壓縮后的文件
var rename = require("gulp-rename");
//引入gulp-concat模塊
var concat = require("gulp-concat");
//文件之間的依賴關(guān)系
var pathFile = ["./script/a.js","./script/b.js","./script/c.js"];
//自定義任務(wù),firstGulp為自定義任務(wù)名
gulp.task("firstGulp",function(){
gulp.src("./script/a.js")
.pipe(uglify())
.pipe(gulp.dest("./dest"))
})
//新增一個auto的任務(wù)
gulp.task("auto",function(){
//watch()監(jiān)聽a.js文件的變動,如果變動,就執(zhí)行firstGulp任務(wù)
//如果監(jiān)聽script下所有文件,只需把第一個參數(shù)改成script/*.js
//gulp.watch("./script/a.js",["firstGulp"]);
gulp.watch("./script/*.js", function(event){
gulp.src(pathFile)
.pipe(uglify())
//合并壓縮為common.js
.pipe(concat("common.js"))
//給壓縮后的文件添加.min后綴
.pipe(rename({suffix: ".min"}))
.pipe(gulp.dest("./dist"));
})
})
//default為gulp默認任務(wù)
gulp.task("default",["auto"])
壓縮后的common.min.js如下:

可以看到,已經(jīng)把3個文件的js代碼合并壓縮到了一個文件中了,說明已經(jīng)實現(xiàn)了合并壓縮js文件。
對于js文件的壓縮差不多就ok了,后面的文章會繼續(xù)講解gulp對于css,less,html以及圖片的處理,還有文件自動添加版本號的功能。
總結(jié)
- 安裝nodejs
- 全局和本地安裝gulp
- 安裝gulp插件
- 新建gulpfile.js文件
- 通過命令提示符運行g(shù)ulp任務(wù)
- gulp常用插件
| 插件名 | 作用 |
|---|---|
| gulp-uglify | 用于壓縮js |
| gulp-watch-path | 用于篩選改動的文件 |
| gulp-rename | 用于重命名壓縮后的文件 |
| gulp-concat | 用于合并文件 |
此系列文章是對gulp前端自動構(gòu)建工具的使用以及總結(jié),文中如有不正之處,還望指正。
原創(chuàng)文章,站在前輩們的經(jīng)驗上的總結(jié),文中如有不正之處,還望指正!