隨著前端諸如webpack,rollup,vite的發展,gulp感覺似乎好像被取代了。其實並沒有,只不過它從臺前退居到了幕後。我們仍然可以在很多專案中看到它的身影,比如elementplus、vant等。現在gulp更多的是做流程化的控制。
比如我們要把一個大象放進冰箱裡就需要 開啟冰箱門->把大象放進冰箱->關上冰箱門,這就是一個簡單的流程,使用gulp就可以規定這些流程,將這個流程自動化。
所以我們可以使用它在專案開發過程中自動執行常見任務。比如打包一個元件庫,我們可能要移除檔案、copy檔案,打包樣式、打包元件、執行一些命令還有一鍵打包多個package等等都可以由gulp進行自定義流程的控制,非常的方便。
本文將主要介紹gulp的一些常用功能
首先全域性安裝gulp的腳手架
npm install --global gulp-cli
然後我們新建資料夾gulpdemo,然後執行 npm init -y,然後在這個專案下安裝本地依賴gulp
npm install gulp -D
此時我們gulp便安裝好了,接下來我們在根目錄下建立gulpfile.js檔案,當gulp執行的時候會自動尋找這個檔案。
每個gulp任務(task)都是一個非同步的JavaScript函數,此函數是一個可以接收callback作為引數的函數,或者返回一個Promise等非同步操作物件,比如建立一個任務可以這樣寫
exports.default = (cb) => {
console.log("my task");
cb();
};
或者這樣寫
exports.default = () => {
console.log("my task");
return Promise.resolve();
};
然後終端輸入gulp就會執行我們這個任務
這兩個其實很好理解,序列就是任務一個一個執行,並行就是所有任務一起執行。下面先看序列演示
const { series, parallel } = require("gulp");
const task1 = () => {
console.log("task1");
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 5000);
});
};
const task2 = () => {
console.log("task2");
return Promise.resolve();
};
exports.default = series(task1, task2);
控制檯輸出結果如下
可以看出執行task1用了5s,然後再執行task2,再看下並行
const { series, parallel } = require("gulp");
const task1 = () => {
console.log("task1");
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 5000);
});
};
const task2 = () => {
console.log("task2");
return Promise.resolve();
};
exports.default = parallel(task1, task2);
可以看出兩個任務是同時執行的
src()和dest()這兩個函數在我們實際專案中經常會用到。src()表示建立一個讀取檔案系統的流,dest()是建立一個寫入到檔案系統的流。我們直接寫一個copy 的範例
在寫之前我們先在我們專案根目錄下新建一個src目錄用於存放我們被複制的檔案,在src下隨便新建幾個檔案,如下圖
然後我們在gulpfile.js寫下我們的copy任務:將src下的所有檔案複製到dist資料夾下
const { src, dest } = require("gulp");
const copy = () => {
return src("src/*").pipe(dest("dist/"));
};
exports.default = copy;
然後執行gulp(預設執行exports.default),我們就會發現根目錄下多了個dist資料夾
下面我們寫個處理less檔案的任務,首先我們先安裝gulp-less
npm i -D gulp-less
然後我們在src下新建一個style/index.less並寫下一段less語法樣式
@color: #fff;
.wrap {
color: @color;
}
然後gulpfile.js寫下我們的lessTask:將我們style下的less檔案解析成css並寫入dist/style中
const { src, dest } = require("gulp");
const less = require("gulp-less");
const lessTask = () => {
return src("src/style/*.less").pipe(less()).pipe(dest("dist/style"));
};
exports.default = lessTask;
然後我們執行gulp命令就會發現dist/style/index.css
.wrap {
color: #fff;
}
我們還可以給css加字首
npm install gulp-autoprefixer -D
將我們的src/style/index.less改為
@color: #fff;
.wrap {
color: @color;
display: flex;
}
然後在gulpfile.js中使用gulp-autoprefixer
const { src, dest } = require("gulp");
const less = require("gulp-less");
const autoprefixer = require("gulp-autoprefixer");
const lessTask = () => {
return src("src/style/*.less")
.pipe(less())
.pipe(
autoprefixer({
overrideBrowserslist: ["> 1%", "last 2 versions"],
cascade: false, // 是否美化屬性值
})
)
.pipe(dest("dist/style"));
};
exports.default = lessTask;
處理後的dist/style/index.css就變成了
.wrap {
color: #fff;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
browser-sync是一個十分好用的瀏覽器同步測試工具,它可以搭建靜態伺服器,監聽檔案更改,並重新整理頁面(HMR),下面來看下它的使用
首先肯定要先安裝
npm i browser-sync -D
然後我們在根目錄下新建index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
hello world
</body>
</html>
然後在gulpfile.js中進行設定
const browserSync = require("browser-sync");
const browserTask = () => {
browserSync.init({
server: {
baseDir: "./",
},
});
};
exports.default = browserTask;
這時候就會啟動一個預設3000埠的頁面. 下面我們看如何監聽頁面變化。
首先我們要監聽檔案的改變,可以使用browserSync的watch,監聽到檔案改變後再重新整理頁面
const { watch } = require("browser-sync");
const browserSync = require("browser-sync");
const { series } = require("gulp");
const reloadTask = () => {
browserSync.reload();
};
const browserTask = () => {
browserSync.init({
server: {
baseDir: "./",
},
});
watch("。/*", series(reloadTask));
};
exports.default = browserTask;
此時改動src下的檔案瀏覽器便會重新整理。
下面我們將index.html引入dist/style/index.css的樣式,然後來模擬一個簡單的構建流
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="../dist/style/index.css" />
</head>
<body>
<div class="wrap">hello world</div>
</body>
</html>
此時我們的流程是 編譯less檔案->將css寫入dist/style->觸發頁面更新
我們gulpfile.js可以這樣寫
const { src, dest } = require("gulp");
const { watch } = require("browser-sync");
const browserSync = require("browser-sync");
const { series } = require("gulp");
const less = require("gulp-less");
const autoprefixer = require("gulp-autoprefixer");
const lessTask = () => {
return src("src/style/*.less")
.pipe(less())
.pipe(
autoprefixer({
overrideBrowserslist: ["> 1%", "last 2 versions"],
cascade: false, // 是否美化屬性值
})
)
.pipe(dest("dist/style"));
};
//頁面重新整理
const reloadTask = () => {
browserSync.reload();
};
const browserTask = () => {
browserSync.init({
server: {
baseDir: "./",
},
});
watch("./*.html", series(reloadTask));
//監聽樣式更新觸發兩個任務
watch("src/style/*", series(lessTask, reloadTask));
};
exports.default = browserTask;
此時無論我們更改的是樣式還是html都可以觸發頁面更新。
後面我會將正在開發的vue3元件庫的樣式打包部分使用gulp處理,如果你對元件庫開發感興趣的話可以關注我,後續會持續更新本系列內容
創作不易,你的點贊就是我的動力!如果感覺這篇文章對你有幫助的話就請點個贊吧,感謝~