前端构建工具 Gulp.js 上手实例
在軟件開(kāi)發(fā)中使用自動(dòng)化構(gòu)建工具的好處是顯而易見(jiàn)的。通過(guò)工具自動(dòng)化運(yùn)行大量單調(diào)乏味、重復(fù)性的任務(wù),比如圖像壓縮、文件合并、代碼壓縮、單元測(cè)試等等,可以為開(kāi)發(fā)者節(jié)約大量的時(shí)間,使我們能夠?qū)W⒂谡嬲匾摹⒂幸饬x的工作,比如設(shè)計(jì)業(yè)務(wù)邏輯,編寫(xiě)代碼等等。
對(duì)很多前端開(kāi)發(fā)人員而言,Grunt?無(wú)疑是這方面的首選。基本上,如果你會(huì)用 JavaScript ,那么在一個(gè)名為?Gruntfile.js?(或者?Gruntfile)的文件中用 Javascript 語(yǔ)言定義自動(dòng)化任務(wù)是非常簡(jiǎn)單的過(guò)程,同時(shí)大量的?第三方插件?例如 JSHint, Sass 以及 Uglify 也使得 Grunt 具有了良好的可擴(kuò)展性。
大多數(shù)情況下,Grunt 一直是前端構(gòu)建工具的首選。但是最近一個(gè)名為?Gulp.js?的新工具正在吸引越來(lái)越多的人的關(guān)注。相比 Grunt, 它具有可讀性更強(qiáng)、更利于理解的配置文件,更簡(jiǎn)單地配置過(guò)程。
接下來(lái)我們就一起來(lái)看看如何安裝 Gulp, 并通過(guò)一個(gè)簡(jiǎn)單的案例讓你感受一下這個(gè)新的構(gòu)建工具。
安裝 Gulp.js
Gulp.js 是基于 Node 的構(gòu)建工具,類(lèi)似 Grunt, 要使用它,你的機(jī)器上需要裝有?Node.js。有關(guān)如何安裝 Node, 這里就不再贅述,可以參考官網(wǎng)的指導(dǎo)。如果你之前完全不了解 Node.js, 可以參考一下?Nettuts+ 上面的系列教程。 有了 Node.js, 安裝 Gulp.js 就非常容易了,只需要通過(guò)?npm?(Node 包管理工具) 來(lái)安裝即可。在命令行模式下執(zhí)行:
| npm?install -g gulp |
這樣就可以將 gulp 以全局方式安裝到你的電腦上,以后可以隨時(shí)通過(guò)命令行的?gulp?命令來(lái)調(diào)用。
在前端項(xiàng)目中配置 Gulp.js
要在你的項(xiàng)目中使用 Gulp, 有幾個(gè)關(guān)鍵的步驟需要完成:
- 安裝兩個(gè)依賴(lài)包
- 安裝你需要的任意插件
- 創(chuàng)建 gulpfile.js 文件,在其中定義你要運(yùn)行的任務(wù)
這些步驟需要在你的項(xiàng)目根目錄下完成。
首先,要安裝依賴(lài)項(xiàng):
| npm?install --save-dev gulp gulp-util |
接下來(lái),安裝我們需要使用到的 Gulp 插件,這些插件同樣也都是 Node 模塊,我們同樣使用?npm?命令來(lái)安裝它們:
| npm?install --save-dev gulp-uglify gulp-concat |
在上面的例子中,安裝了兩個(gè)插件?gulp-uglify?和?gulp-concat, 通過(guò)它們可以對(duì) Javascript 文件進(jìn)行合并和壓縮。
注意這里使用了?--save-dev?參數(shù)來(lái)安裝 Gulp 依賴(lài)和插件,加上這個(gè)參數(shù)以后,在安裝這些包的同時(shí),也會(huì)把它們添加到我們的包配置文件?package.json:
| {??"devDependencies": {????"gulp":?"^3.6.2",????"gulp-concat":?"^2.2.0",????"gulp-uglify":?"^0.2.1",????"gulp-util":?"^2.2.14"??}} |
這樣可以確保項(xiàng)目所需的依賴(lài)包可以便捷地通過(guò)?npm?來(lái)進(jìn)行安裝。 如果你的項(xiàng)目沒(méi)有?package.json?文件,可以在命令行通過(guò)?npm init?來(lái)創(chuàng)建, 也可以通過(guò)文本編輯器創(chuàng)建。這是?npm?相關(guān)的知識(shí),這里就不細(xì)說(shuō)了。
在前面的例子中,只安裝了兩個(gè)插件,Gulp 提供了超過(guò)?200 個(gè)插件, 涵蓋了前端開(kāi)發(fā)流程中的很多工作,包括但不限于:
- LiveReload (gulp-livereload)
- JSHint (gulp-jshint)
- Sass (gulp-sass)
- CoffeeScript file compilation (gulp-coffee)
還有很多,可以到?Gult plugins?進(jìn)行搜索。
Gulpfile.js 文件
與 Grunt 一樣, Gulp 也有一個(gè)同名配置文件,叫做?gulpfile.js, 在這個(gè)文件里定義需要用到什么插件,執(zhí)行什么任務(wù),如何執(zhí)行等等。 這個(gè)文件應(yīng)該存放在你的項(xiàng)目根目錄下。
到目前為止,一切看起來(lái)都和 Grunt 沒(méi)什么區(qū)別,那么為什么要介紹 Gulp 呢?接下來(lái)就是它的優(yōu)勢(shì)所在了。?gulpfile.js?的語(yǔ)法非常簡(jiǎn)單直接,具有非常好的可讀性,便于理解。看一下例子:
| var gulp=require('gulp'),????gutil=require('gulp-util'),????uglify=require('gulp-uglify'),????concat=require('gulp-concat'); |
這就是一條非常簡(jiǎn)單的 Javascript 變量定義語(yǔ)句,它告訴 Gulp 我們需要哪些插件來(lái)完成下面的任務(wù)定義。
接下來(lái),我們要定義需要 Gulp 去運(yùn)行的任務(wù)。在這個(gè)例子中,需要 Gulp 去完成兩件事:
- 壓縮 Javascript 文件
- 合并 Javascript 文件
在 Gulp 中,定義任務(wù)非常直接,就是調(diào)用 Javascript 的方法。我們通過(guò) Gulp 提供的?task()?方法來(lái)定義任務(wù):
| gulp.task('js',?function() {????gulp.src('./js/*.js')????????.pipe(uglify())????????.pipe(concat('all.js'))????????.pipe(gulp.dest('./js'));}); |
看一下上面的代碼,gulp.task(name, callback)?方法需要兩個(gè)參數(shù),第一個(gè)是任務(wù)名稱(chēng),第二個(gè)是回調(diào)函數(shù)。這個(gè)一看就明白了,沒(méi)什么要解釋的。看一下回調(diào)函數(shù)里面的代碼:
| gulp.src('./js/*.js') |
src()?方法用來(lái)指定要處理的 js 文件的位置,它會(huì)獲取匹配到的所有 js 文件的路徑,并將它們轉(zhuǎn)換為可以傳遞給插件進(jìn)行處理的“流”。這是 Node.js 的?Streams API?的組成部分,也是 Gulp 能夠?qū)崿F(xiàn)如此簡(jiǎn)潔的 API 語(yǔ)法的原因。
| .pipe(uglify()) |
pipe()?方法獲取剛才通過(guò)?src()?方法獲得并傳遞過(guò)來(lái)的“流”,并將其傳遞給指定的插件。本例中是 uglify 插件。
| .pipe(concat('all.js')) |
與 uglify 一樣,concat 插件通過(guò)?pipe()?方法接收經(jīng)過(guò)上一個(gè)方法處理之后返回的“流”,并把他們?cè)摗傲鳌敝械乃?Javascript 文件合并為一個(gè)名為 "all.js" 的文件。
| .pipe(gulp.dest('./js')); |
最后,通過(guò) Gulp 的?dest()?方法, "all.js" 被寫(xiě)入到我們指定的目錄。整個(gè)過(guò)程非常直觀,易于理解。可以想象一下?jQuery?的鏈?zhǔn)秸{(diào)用,也可以想象一下 *nix 系統(tǒng)下的?grep,?awk?這些命令。
我們要做的最后一件事,是指定 Gulp 的默認(rèn)任務(wù),讓它執(zhí)行我們剛才定義的 "js" 任務(wù)。
| gulp.task('default', ['js']); |
完整的?gulpfile.js:
| // 定義依賴(lài)項(xiàng)和插件var gulp=require('gulp'),????gutil=require('gulp-util'),????uglify=require('gulp-uglify'),????concat=require('gulp-concat');// 定義名為 "js" 的任務(wù)gulp.task('js',?function(){????gulp.src('./js/*.js')????????.pipe(uglify())????????.pipe(concat('all.js'))????????.pipe(gulp.dest('./js'));});// 定義默認(rèn)任務(wù)gulp.task('default', ['js']); |
回到命令行(項(xiàng)目根目錄),輸入?gulp, 回車(chē)。 Gulp 找到?gulpfile.js?文件,加載依賴(lài)的插件,啟動(dòng)默認(rèn)任務(wù),然后執(zhí)行我們的 "js" 任務(wù), 你可以看到最終結(jié)果
Gulp 還提供了一個(gè)名為?watch()?的方法,可以自動(dòng)檢查指定的資源(文件)的變化。這樣就可以在文件發(fā)生變化時(shí)自動(dòng)執(zhí)行特定的任務(wù),不必每次修改了文件就要回到命令行手動(dòng)執(zhí)行?gulp.
| gulp.watch('./js/*.js', ['js']); |
這行代碼執(zhí)行時(shí), Gulp 會(huì)持續(xù)監(jiān)控?./js/?目錄下所有的 js 文件,一旦文件發(fā)生變化,就會(huì)自動(dòng)重新執(zhí)行 "js" 任務(wù)來(lái)合并和壓縮文件。當(dāng)然,這行代碼通常也要放到某個(gè)任務(wù)中去運(yùn)行。
轉(zhuǎn)到 Gulp.js
在我開(kāi)始使用 Grunt 之前的幾年里,一直是使用?濤哥?開(kāi)發(fā)的?CssGaga?來(lái)做前端構(gòu)建工具。這是當(dāng)時(shí)我們工作標(biāo)準(zhǔn)流程的一部分,它非常強(qiáng)大。
后來(lái)從?isux?轉(zhuǎn)崗到?TGideas, 工作流程發(fā)生了巨大的變化,同時(shí)我在 Windows / Linux / Mac 不同平臺(tái)下工作的時(shí)間也越來(lái)越多,于是轉(zhuǎn)向了 Grunt. 與 CssGaga 相比, Grunt 需要自己去尋找需要的插件,在每個(gè)項(xiàng)目中進(jìn)行適當(dāng)?shù)呐渲脕?lái)完成構(gòu)建工作,但是它跨平臺(tái)、按需組合功能的特性較好地滿足了我的需要。之后又聽(tīng)說(shuō)過(guò)、嘗試過(guò)一些前端構(gòu)建工具,但都沒(méi)有讓我放棄 Grunt.
第一次看到 Gulp 的介紹時(shí),就被它的配置語(yǔ)法所吸引。因?yàn)閷?duì)于任何一個(gè)接觸過(guò) Node.js 的人來(lái)說(shuō),這語(yǔ)法是在是太舒服了。一看就懂,看一遍就會(huì),不是嗎?暫時(shí)來(lái)說(shuō),它的插件數(shù)量還沒(méi)有 Grunt 那么多那么全面,不過(guò)日常的前端任務(wù),還是都涵蓋了,而且有一些實(shí)現(xiàn)得比 Grunt 平臺(tái)上的更棒。而且它的插件庫(kù)也不斷在增長(zhǎng),尤其是現(xiàn)在有這么多開(kāi)發(fā)者對(duì)它有興趣,相信它會(huì)得到快速的發(fā)展。
總結(jié)
以上是生活随笔為你收集整理的前端构建工具 Gulp.js 上手实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 探寻宝藏
- 下一篇: JSP生成静态HTML页面的实践方法和设