Stories

Detail Return Return

gulp使用指南

gulp 是一個使用“流”來實現自動化的工具,正如 官方文檔 首頁展示的這副動圖一樣,以“流動”的狀態去處理 TypeScript、PNG、Markdown 資源。

與webpack比較

類別 webpack gulp
核心理念 module bundler task runner
執行任務 模塊化 定義任務、等待執行
構建方式 loader 文件Stream
支持插件

gulp 相比 webpack 思想會更加簡單、易用,更適合一些自動化任務(比如Jquery、編譯文件上傳到服務器等功能),但它默認不支持模塊化,所以大型的項目(Vue、React、Angle)並不會使用它。

執行任務

安裝依賴

webpack 一樣,gulp 可以全局安裝,也可以在項目局部安裝,這裏通過 npm install gulp 僅在當前項目安裝

配置文件

webpack 中默認的配置文件為 webpack.config.js,而 gulp 中默認配置文件為 gulpfile.js,根目錄創建文件,定義一個函數,將它導出,這就定義了一個簡單的任務。

const foo = () => {
  console.log('foo');
};

module.exports = {
  foo,
};
編譯文件

執行 npx gulp foo 命令編譯任務,在 gulp 後面跟上函數名 foo 告知執行的任務名稱

但此時編譯會報錯,提醒任務沒有完成,是否忘記了發送異步任務完成的信號

異步任務

這是因為默認情況所有任務是異步的,想要結束有兩種方式

  1. 返回固定的內容,stream、promise、event emitter、child process 或 observable 類型
  2. 接受一個 callback 作為參數,調用 callback 函數任務結束

這裏使用第二種方式

const foo = (cb) => {
  console.log('foo');
  cb();
};

再次執行 npx gulp foo,此時編譯成功,執行時間 2.59ms

默認任務

上面執行命令時,gulp 後面跟了任務名稱 foo,如果不跟名稱時,執行的是默認任務,需要在 gulpfile.js 中導出默認任務

module.exports.default = (cb) => {
  console.log('default task');
  cb();
};

此時可以看到輸出默認任務

串行並行

當存在多個任務需要進行組合時,可以通過 gulp 提供的方法,series 表示串行,parallel 表示並行。

const { series, parallel } = require('gulp');
const task1 = (cb) => {
  setTimeout(() => {
    console.log('task1');
    cb();
  }, 2000);
};

const task2 = (cb) => {
  setTimeout(() => {
    console.log('task2');
    cb();
  }, 2000);
};

const task3 = (cb) => {
  setTimeout(() => {
    console.log('task3');
    cb();
  }, 2000);
};

const seriesTask = series(task1, task2, task3);
const parallelTask = parallel(task1, task2, task3);
module.exports = {
  seriesTask,
  parallelTask,
};

串行會等上一個任務執行完成,再執行下一個,任務的完成時間為所有任務的總和,並行就會將所有任務一起執行。

讀取文件、監聽

在項目的 src 文件夾下定義 index.js 文件,通過 gulp 暴露的 src()dest() 方法用於處理計算機上存放的文件。

const { src, dest } = require('gulp');
const task = () => {
  return src('src/*.js').pipe(dest('dist'));
};
module.exports = {
  task,
};

此時src文件夾下的 index.js 文件被讀取到 dist 文件夾下

此時的 js 代碼沒有做 es6 - es5 的轉化,也沒有壓縮,想要達到這些效果,需要使用 gulp 的插件,分別是 gulp-babelgulp-terser,定義方式和 webpack 中 babel 和 terser是一致的,不太瞭解 babel 和 terser 的朋友可以點鏈接查看。

需注意,使用 gulp-babel 需要安裝 babel 的核心庫 @babel/core 以及指定編譯規則用到的預設 @babel/preset-env 或者其它插件。

const { src, dest } = require('gulp');
const babel = require('gulp-babel');
const terser = require('gulp-terser');

const task = () => {
  return src('src/*.js')
    .pipe(babel({ presets: ['@babel/preset-env'] }))
    .pipe(terser({ mangle: { toplevel: true } }))
    .pipe(dest('dist'));
};

module.exports = {
  task,
};

通過 pipe() 處理完資源返回一個“流”文件交給下一個插件處理,此時 dist 文夾下的 index.js 資源就進行了代碼轉換和壓縮。

webpack 在編譯的時候提供了 --watch 屬性,當源碼資源發生變化時,自動重新編譯,gulp 也提供這樣的功能,使用 watch() 來實現。

const { watch } = require('gulp');
watch('src/*.js', task);

使用 watch 後,編譯不會結束,每當監聽的文件修改並保存時,重新編譯。

總結

  • gulp 主要以“流”的方式來處理資源,沒有模塊化,不適合大型項目。
  • gulp 每次處理即開啓異步任務,可以並行、串行、監聽資源的更新。
  • 使用插件,gulp 也能實現代碼轉化、壓縮等功能。

以上就是 gulp 的介紹, 更多有關 前端工程化 的內容可以參考我其它的博文,持續更新中~

user avatar
0 users favorite the story!

Post Comments

Some HTML is okay.