歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 是時候升級你的gulp到4.0了

是時候升級你的gulp到4.0了

日期:2017/3/1 9:26:50   编辑:Linux編程

隨著前端工程化的推進,相信越來越多的項目都用上了自動化構建。對前端構建來說,使用最多的莫過於 grunt 和 gulp 。

本文的主角是gulp,所以花一兩句話來介紹gulp還是有必要的。

gulp是一款基於 stream 的前端構建工具,由於底層使用stream,可以將多個任務無縫串連在一起,相比使用臨時文件的grunt要快不少;同時也不用像grunt一樣寫一大堆配置文件,每一個任務都可以可編程的來完全控制邏輯。

gulp比grunt“快”這是公認的事實,這裡不再過多比較兩者之間的差異,還是那句話,各有千秋吧。

gulp 4.0的變化

扯完了廢話,開始進入正題。

gulp團隊大概在兩個月前提交了 4.0分支 ,新版本帶來了新的api,新api給任務流程控制帶來了“革命性”的進步。

但新版本並未提交到npm,可能現在連alpha都算不上吧,不過還是可以先進行體驗的。

安裝gulp 4.0

想體驗4.0只有通過github安裝,執行以下兩條命令即可在本地暢爽地使用gulp 4.0了。

npm install gulpjs/gulp#4.0 -g

npm install gulpjs/gulp#4.0 --save-dev

gulp 4.0相對以前的版本發生了不少變化

  1. 使用新的任務系統 bach ,替換了老版本使用的 orchestrator

也許會更快些?實際上gulp已經很快了,除非是超大型項目,否則幾乎不用擔心gulp構建會花太多時間,不過尋求更快總是好的。

  1. 移除了gulp.task傳遞三參數的用法

即這種用法將報錯

gulp . task ( 'watch' , [ 'default' ] , function ( ) {

// TODO

// watch file

} ) ;

在gulp4.0之前,這種用法將會保證default任務先執行完再執行watch任務,gulp的任務流程控制就是這麼實現的,不過這也是老版本gulp的弱點之一。

對我們這些普通使用者來說,最大的變化有兩點

gulp.task 的變化

gulp官方建議:

  1. 當我們想在命令行通過敲 gulp taskname 的方式執行一個任務,這時候你應該使用 gulp.task 注冊 taskName
  2. 當一個較復雜的任務(如dist)由很多個子任務組合而成的時候,子任務使用具名函數即可,不用單獨為每個子任務進行注冊,而只需將 dist 使用 gulp.task 進行注冊,以前的版本則必須將每一個子任務都先使用 gulp.task 進行注冊,然後再組合出 dist ,詳細用法見最後的例子。

gulp.task又增加了一種用法,即傳遞一個具名函數作為參數,將自動注冊以該函數名命名的任務

function compile ( ) {

// TODO

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

. pipe ( uglify ( ) )

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

}

gulp . task ( compile ) ;

等同於

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

// TODO

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

. pipe ( uglify ( ) )

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

} ) ;

兩者都可以通過命令行運行 gulp compile 執行任務

增加了 gulp.seriesgulp.parallel

哈哈,解放軍來了。

如果你是gulp深度使用者,你一定不止一次吐槽過gulp的任務流程難以控制,就像一條復雜的電路一樣,電路上很多電阻都是串聯加並聯的方式連接在一起,gulp一個復雜的任務同樣也是由很多個子任務以串聯(同步)加並聯(異步)的方式連接在一起的。

老版本的gulp對多個異步任務很難控制,必須借助於第三方模塊,如 run-sequenceevent-stream 等,效果也並不理想。

現在gulp帶來了兩個新的api: gulp.seriesgulp.parallel ,這兩個革命性的api將幫助開發者解決惱人的任務流程控制問題。

下面就來見識新api的神奇之處吧。

example

以開發中最常見的dist任務為例,使用gulp首先得分解任務,dist大致分解成子任務如下

  1. 刪除開發目錄dev, clean-dev
  2. 刪除發布目錄dist, clean-dist
  3. 合圖並修改css中圖片引用, sprite
  4. 預編譯css(如sass)到dev, compile-css
  5. 預編譯js到dev, compile-js
  6. 從src拷貝html到dev, copy-html
  7. 對dev下面的js/css進行md5,再拷貝到dist, reversion
  8. 替換dev下html中js/css進行過md5之後的文件路徑,並拷貝到dist, replcae

這只是一個普通的dist任務,我將dist拆得比較細並省略了壓縮合並等常規任務,大致由以上8個步驟組成。

拆的粒度完全由自己控制,達到方便復用又便於理解的目的就行。

使用老版本的gulp,首先需要對每一個任務進行注冊,這裡只是為了說明問題,我省略了任務的具體代碼。

gulp . task ( 'clean-dev' , function ( ) { // TODO});

gulp . task ( 'clean-dist' , function ( ) { // TODO});

gulp . task ( 'sprite' , function ( ) { // TODO});

gulp . task ( 'compile-css' , function ( ) { // TODO});

gulp . task ( 'compile-js' , function ( ) { // TODO});

gulp . task ( 'copy-html' , function ( ) { // TODO});

gulp . task ( 'reversion' , function ( ) { // TODO});

gulp . task ( 'replcae' , function ( ) { // TODO});

然後,我們來理一理任務的流程,為了讓任務執行效率更高,盡量保證能同時執行的都同時執行,這裡簡單畫了個流程圖來表示任務的流程,箭頭表示先後順序。

可以看到圖中既存在同步又存在異步的任務,需要實現這樣的流程,我們還需要修改和注冊額外的幾個任務,並借助run-sequence等第三方模塊。

gulp . task ( 'compile-css' , [ 'sprite' ] ) ;

gulp . task ( 'dev' , [ 'clean-dev' ] , function ( ) {

runSecquence ( [ 'compile-css' , 'compile-js' , 'copy-html' ] ) ;

} ) ;

gulp . task ( 'md5' , [ 'dev' , 'clean-dist' ] , function ( ) {

runSecquence ( 'reversion' ) ;

} ) ;

gulp . task ( 'dist' , [ 'md5' ] , function ( ) {

runSecquence ( 'replcae' ) ;

} ) ;

gulp官方推薦將任務最小化,每一個任務只做一件明確的事,可以看到任務拆得越細需要注冊的任務就越多,為了處理同時涉及到同步和異步的任務,需要引進額外的中間任務來銜接,在代碼上也不夠自然。

如果使用gulp 4.0,只用這樣就行了

function cleanDev ( ) { // TODO}

function cleanDist ( ) { // TODO}

function sprite ( ) { // TODO}

function compileCss ( ) { // TODO}

function compileJs ( ) { // TODO}

function copyHtml ( ) { // TODO}

function reversion ( ) { // TODO}

function replcae ( ) { // TODO}

gulp . task ( 'dist' , gulp . series (

gulp . parallel (

gulp . series (

cleanDev ,

gulp . parallel (

gulp . series (

sprite ,

compileCss

) ,

compileJs ,

copyHtml

)

) ,

cleanDist

) ,

reversion ,

replcae

) ) ;

gulp.seriesgulp.parallel 都可以接受以 gulp.task 注冊的任務名干脆就是一個(多個)函數,省去了一大堆gulp.task的代碼,同時也達到了任務復用的目的,將子任務經過不同的組合又可以產生新的任務。

結合流程圖,上面的代碼還是很好理解的。

另外再說一點,只要在gulpfile.js中沒有使用gulp.task傳三個參數的用法,gulp 4.0也是兼容老版本的gulpfile.js的。

官方升級日志 中也列出了一些其他的說明,想升級到4.0又想完全兼容老版本gulpfile.js的開發者最好還是看看咯。

Copyright © Linux教程網 All Rights Reserved