YehYeh 記事本2.0

Version 0.8.3

竹科碼農的記事本

GulpTask

建立任務

  • Gulp 裡的一個任務即為一個JavaScript函式
    • 函式的參數通常為一個可回呼(Call Back)的函式
    • 回傳值通常是stream、promise、event emitter、child process 或 observable

任務類型

  • 公開任務(Public tasks)
    • 可以用 gulp 命令直接呼叫
    • 在 gulpfile 中要 export
  • 私有任務(Private tasks)
    • 在內部使用
    • 通常作用來給series()或parallel()使用

例: 公開任務及私有任務

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

// 公開函式(有被export)可以被 gulp 指令直接叫用,也可以被用在series()中
function build(cb) {
  // body omitted
  cb();
}

// 私有函式(沒有被export)
function clean(cb) {
  // body omitted
  cb();
}

exports.build = build;          // 導出 build
exports.default = series(clean, build);

組合任務

  • 將獨立的任務組合成一組任務
  • 可以用 series()parallel()
    • series() : 任務按順序執行
    • parallel() : 任務盡可能同時一起執行(平行處理)
  • series()parallel() 可以互相巢狀使用到任意深度

例: 循序執行 series()

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

function transpile(cb) {    /* 省略 */ cb();   }
function bundle(cb)    {    /* 省略 */ cb();   }
}

exports.build = series(transpile, bundle);

例: 平行處理 parallel()

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

function javascript(cb) {    /* 省略 */ cb();   }
function css(cb)        {    /* 省略 */ cb();   }

exports.build = parallel(javascript, css);

例: series()與paralle()互相巢狀使用

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

function clean(cb)        { /* 省略 */  cb(); }
function cssTranspile(cb) { /* 省略 */  cb(); }
function cssMinify(cb)    { /* 省略 */  cb(); }
function jsTranspile(cb)  { /* 省略 */  cb(); }
function jsBundle(cb)     { /* 省略 */  cb(); }
function jsMinify(cb)     { /* 省略 */  cb(); }
function publish(cb)      { /* 省略 */  cb(); }

exports.build = series(
  clean,
  parallel(
    cssTranspile,
    series(jsTranspile, jsBundle)
  ),
  parallel(cssMinify, jsMinify),
  publish
);

例: 錯誤的寫法

  • 在組合任務中,如果有多個任務叫用同一個任務(Clean),可能會產生無法預估的結果
const { series, parallel } = require('gulp');

const clean      = function(cb) {    cb();   }

const css        = series(clean, function(cb) {    cb();   });
const javascript = series(clean, function(cb) {     cb();   });

exports.build = parallel(css, javascript);

例: 重構 錯誤的寫法

  • series()先執行clean任務,再同時執行css和javascript任務
  • 也就是每個任務都寫成獨立的,不要呼叫其它任務
  • 最後再由exports.build指定任務執行的順序
const { series, parallel } = require('gulp');

const clean      = function(cb) {  cb();   }
const css        = function(cb) {  cb();   }
const javascript = function(cb) {  cb();   }

exports.build = series(clean, parallel(css, javascript));

任務(task)完成通知

  • gulp不在支援非同步任務(Synchronous tasks)
  • 當任務回傳 stream、promise、event emitter、child process 或 observable 時,gulp會看成功或錯誤來決定要繼續執行或結束執行
  • 任務出錯時,gulp會立刻結束執行並顯示錯誤
  • 任務組合出錯時
    • series() : 任何一個任務出錯,整個任務組合都會結束
    • parallel() : 任何一個任務出錯,整個任務組合都會結束 ⇒ 有的任務可能執行完,有的沒執行完

例: 任務(task)完成通知 - 使用 callback

  • 如果任務沒有回傳任何內容,要呼叫cb()來讓gulp知道任務已經結束
function callbackTask(cb) {  cb();  /* 在非同步執行時,要呼叫cb() */ }
exports.default = callbackTask;
  • 可以用 Error 當作cb的參數,告訴 gulp 任務的錯誤
function callbackError(cb) {
  cb(new Error('kaboom'));
}
exports.default = callbackError;
  • 通常會將cb傳給另一個API,而不是自己呼叫cb()
const fs = require('fs');

function passingCallback(cb) {
  fs.access('gulpfile.js', cb);
}

exports.default = passingCallback;

例: 任務(task)完成通知 - 回傳 stream

const { src, dest } = require('gulp');
function streamTask() {  return src('*.js').pipe(dest('output'));  }
exports.default = streamTask;

例: 任務(task)完成通知 - 回傳 promise

function promiseTask() {  return Promise.resolve('the value is ignored');  }
exports.default = promiseTask;

例: 任務(task)完成通知 - event emitter

const { EventEmitter } = require('events');

function eventEmitterTask() {
  const emitter = new EventEmitter();  
  setTimeout(() => emitter.emit('finish'), 250);  // Emit has to happen async otherwise gulp isn't listening yet
  return emitter;
}

exports.default = eventEmitterTask;

例: 任務(task)完成通知 - child process

const { exec } = require('child_process');
function childProcessTask() {  return exec('date');  }
exports.default = childProcessTask;

例: 任務(task)完成通知 - observable

const { Observable } = require('rxjs');
function observableTask() {  return Observable.of(1, 2, 3);  }
exports.default = observableTask;
Last updated on 2020-04-02
Published on 2020-04-02
Edit on GitHub