前端工程構建之談:gulp3要不要升級到Gulp4

freephp發表於2021-01-27

關於升級還是不升級,這是一個哲學問題。

gulp4的語法更加現代,支援ES6的大部分寫法,使用exports的方式去暴露任務組合,更加靈活和便捷。

gulp4同時也提供了很多強大的API,例如parallel()和series()。此外,gulp4不再支援同步任務,所以可以看到編寫任務的時候也不再推薦使用.task()方法去編寫,而是獨立定義一個函式方法,然後用return去返回一個回撥函式的結果。例如一個處理的css的任務,定義如下。

function minHeaderCss() {
    // 這是一個回撥函式的返回物件,本身也是非同步的
    return src([
        './static/css/header.css',
        './static/css/boot.css',
        './static/css/wrap.css',
        './static/css/feedback.css',
        './static/css/pronemove.css'
    ])
    .pipe(minCss())
    .pipe(concat('main_header.min.css'))
    .pipe(dest('./static/css/min/'));
}

parallel()是並行執行多個任務(task),一個任務的錯誤將整個任務組合都結束,但是其他並行的任務可能執行完,也可能執行完。
series()是順序執行,任何一個任務出錯,所有後續任務都停止,有點單執行緒的感覺。
這兩個方法都可以從gulp裡面獲得,如下。

const { series, parallel } = require('gulp');

只需要將需要執行的任務新增到series()或者parallel()裡面即可:

const { series, parallel } = require('gulp');

function javascript(cb) {
  // body omitted
  cb();
}

function css(cb) {
  // body omitted
  cb();
}

exports.build = series(javascript, css);

exports.buildParallel = parallel(javascript, css)

如果想執行build任務組合,那麼在命令列中執行如下語句:

gulp build

至於使用哪種方式,還是要是否構建過程很漫長。如果構建的步驟多,任務重,時間又長,肯定有限考慮使用parallel()來並行構建任務組合。
不同的任務組合還可以進行二次組合,可以對一些適合順序執行的任務使用series(),對一些適合並行的任務使用parallel()。例如一些需要babel編譯的Sass和js的任務使用parallel(),一個比較完整的構建指令碼如下所示:

const {src, dest, watch, series, parallel, connect} = require('gulp');
const babel=require('gulp-babel');
const revAll = require('gulp-rev-all');
const cssver = require('gulp-make-css-url-version');
const del = require('del');
const htmlmin = require('gulp-htmlmin');

// 可以使用ES6 => 語法來編寫任務
const babelCss = () => src(['./css/**/*.css'])
.pipe(cssver())
.pipe(cleancss({compatibility: 'ie7', format: 'keep-breaks', keepSpecialComments :'*'}))
.pipe(dest('./dist/css/'))
.pipe(connect.reload());

function babelJs() {
    return src(['./js/**/*.js'])
           .pipe(babel({presets: ['@babel/env']}))
           .pipe(uglify({
                mangle:true,
                compress:true})
           .pipe(dest('./dist/js/'))
           .pipe(revAll.manifestFile())
           .pipe(dest('./dist/rev/'));
}

function clean() {
    return del('./dist');
}

function babelHtml() {
    return src(['./app/tpl/*.html'])
            .pipe(htmlmin({
                removeComments: true,
                collapseWhitespace: true
            }))
            .pipe(dest('./dist/html/'));
}

// 巢狀使用series和parallel
export.build = exports.build = series(clean,parallel(babelJs, babelCss),babelHtml);

這還是一個簡易的構建指令碼,還缺少一個watch,監聽專案中css、js、html檔案的變化,一旦發生變化就觸發對應的方法。gulp服務一直執行著,實時重新整理。
我個人認為,如果是長期維護的專案,還是可以考慮擁抱gulp4,畢竟Gulp4的強大,是真香!

相關文章