前期準備工作
-
首先確保本機安裝了 node
安裝 gulp 命令列工具
npm install --global gulp-cli
在專案目錄下建立 package.json 檔案
npm init -y
安裝 gulp,作為開發時依賴項
npm install --save-dev gulp
檢查 gulp 版本
gulp --version
PS D:\a-個人專案管理\使用Gulp搭建專案\gulp-building> gulp --version
CLI version: 2.3.0
Local version: 4.0.2
建立配置檔案
在根目錄下新建 src
資料夾和 gulpfile.js
檔案
在 src
目錄下新建如下檔案,其中 index.html
作為我們的入口頁面
gulp 中常用方法解釋
src
建立一個流,用於從檔案系統讀取 Vinyl 物件。
函式原型
src(globs, [options])
返回值
返回一個可以在管道的開始或中間使用的流,用於根據給定的 globs 新增檔案。
globs
glob 是由普通字元和/或通配字元組成的字串,用於匹配檔案路徑。可以利用一個或多個 glob 在檔案系統中定位檔案。
src()
方法接受一個 glob 字串或由多個 glob 字串組成的陣列作為引數,用於確定哪些檔案需要被操作。glob 或 glob 陣列必須至少匹配到一個匹配項,否則 src()
將報錯。當使用 glob 陣列時,將按照每個 glob 在陣列中的位置依次執行匹配 - 這尤其對於取反(negative) glob 有用。
特殊字元: * (一個星號)
在一個字串片段中匹配任意數量的字元,包括零個匹配。對於匹配單級目錄下的檔案很有用。
下面這個 glob 能夠匹配類似 index.js
的檔案,但是不能匹配類似 scripts/index.js
或 scripts/nested/index.js
的檔案。
'*.js'
特殊字元: ** (兩個星號)
在多個字串片段中匹配任意數量的字元,包括零個匹配。 對於匹配巢狀目錄下的檔案很有用。請確保適當地限制帶有兩個星號的 glob 的使用,以避免匹配大量不必要的目錄。
下面這個 glob 被適當地限制在 scripts/
目錄下。它將匹配類似 scripts/index.js
、scripts/nested/index.js
和 scripts/nested/twice/index.js
的檔案。
'scripts/**/*.js'
desc
dest()
接受一個輸出目錄作為引數,並且它還會產生一個 Node 流(stream),通常作為終止流(terminator stream)。當它接收到通過管道(pipeline)傳輸的檔案時,它會將檔案內容及檔案屬性寫入到指定的目錄中。gulp 還提供了 symlink()
方法,其操作方式類似 dest()
,但是建立的是連結而不是檔案( 詳情請參閱 symlink()
)。
大多數情況下,利用 .pipe()
方法將外掛放置在 src()
和 dest()
之間,並轉換流(stream)中的檔案。
series
將任務函式和/或組合操作組合成更大的操作,這些操作將按順序依次執行。對於使用 series()
和 parallel()
組合操作的巢狀深度沒有強制限制。
用法
const { series } = require('gulp');
function javascript(cb) {
// body omitted
cb();
}
function css(cb) {
// body omitted
cb();
}
exports.build = series(javascript, css);
parallel
將任務功能和/或組合操作組合成同時執行的較大操作。對於使用 series()
和 parallel()
進行巢狀組合的深度沒有強制限制。
用法
const { parallel } = require('gulp');
function javascript(cb) {
// body omitted
cb();
}
function css(cb) {
// body omitted
cb();
}
exports.build = parallel(javascript, css);
watch
監聽 globs 並在發生更改時執行任務。任務與任務系統的其餘部分被統一處理。
用法
const { watch } = require('gulp');
watch(['input/*.js', '!input/something.js'], function(cb) {
// body omitted
cb();
});
啟動專案並熱更新
安裝
npm install --save-dev browser-sync
使用
在 gulpfile.js
檔案中配置如下程式碼
const { series, parallel, src, dest, watch } = require("gulp");
const browserSync = require("browser-sync"); // 啟動專案
const reload = browserSync.reload; // 更新頁面
// 啟動專案
function server() {
browserSync({
notify: false, // 關閉通知,頁面右上角不會出現彈框
port: 3000, // 啟動 3000 埠
server: {
baseDir: ["src"], // 配置根目錄,在這個根目錄下啟動伺服器
},
callbacks: {
// 專案啟動成功後執行的方法
ready: () => {
console.log("開始監控開發資料夾");
// 設定要監控的頁面,當被監控頁面發生變化時執行過載方法
const watcher = watch(["src/**/*.html", "src/**/*.js", "src/**/*.css"]);
// 監聽到變化後執行
watcher.on("change", () => {
// 頁面變化後執行過載方法
reload();
});
},
},
});
}
// 公開 server 任務,執行 gulp server 執行啟動任務
exports.server = server;
執行
然後在控制檯中執行 gulp server
執行成功如上圖所示,同時自動瀏覽器
壓縮 HTML
安裝
npm install --save-dev gulp-htmlmin gulp-html-replace
配置
下面用到的 gulp-html-replace
替換檔案引用地址,我們需要在 html
中需要替換的地方通過註釋形式來告訴配置檔案我要替換那個地址
標記格式,標記後我們就可以通過標記的名稱來對引用地址進行替換
<!-- build:css -->
<link rel="stylesheet" href="./public/css/index.css">
<!-- endbuild -->
<!-- build:js -->
<script src="./public/js/index.js"></script>
<!-- endbuild -->
配置程式碼
const { series, parallel, src, dest, watch } = require("gulp");
const htmlmin = require("gulp-htmlmin"); // 壓縮html
const htmlreplace = require("gulp-html-replace"); // 替換檔案引用地址
// 配置壓縮html的規則
const indexOptions = {
removeComments: true, // 清除html註釋
collapseWhitespace: true, // 壓縮html
collapseBooleanAttributes: true, //省略布林屬性的值 <input checked="true"/> -> <input checked />
removeEmptyAttributes: true, // 刪除所有空格作為屬性值 <inpit id=""/> -> <inpit/>
minifyCss: true, // 壓縮頁面中的css
minifyJs: true, // 壓縮頁面中的js
};
// 壓縮打包html
function html() {
return src(["src/view/**/*.html"])
.pipe(htmlmin(indexOptions)) // 使用上面定義的壓縮配置進行壓縮html
.pipe(dest("dist/html/")); // 將檔案寫入到 dist/html/ 目錄下
}
// 單獨處理一下 index.html
function indexhtml() {
return src("src/index.html")
.pipe(
htmlreplace({
// 替換標記的路徑
css: "css/index.css",
js: "js/index.min.js",
})
)
.pipe(htmlmin(indexOptions)) // 使用上面定義的壓縮配置進行壓縮html
.pipe(dest("dist/"));
}
壓縮 CSS
安裝
npm install --save-dev gulp-csso @babel/core
配置
const { series, parallel, src, dest, watch } = require("gulp");
const csso = require("gulp-csso"); // 壓縮css
// 壓縮css
function css() {
return src("src/public/css/**/*.css").pipe(csso()).pipe(dest("dist/css"));
}
壓縮 JS
安裝
npm install --save-dev gulp-uglify gulp-babel gulp-rename gulp-string-replace
配置
const { series, parallel, src, dest, watch } = require("gulp");
const babel = require("gulp-babel"); // 支援es6以及模組化
const uglify = require("gulp-uglify"); // 壓縮js程式碼
const rename = require("gulp-rename"); // 重新命名檔案
const replace = require("gulp-string-replace"); // 替換字串
// 壓縮js
function js() {
// 即使這個任務不需要回撥,但也要有一個預設的回撥方法,也可以return
// cb();
return src("src/public/js/*.js")
.pipe(babel())
.pipe(uglify()) // 壓縮js程式碼
.pipe(replace(/assetApi/g, "https://www.gulpjs.com.cn")) // 替換程式碼中的 "assetApi"
.pipe(rename({ extname: ".min.js" })) // 將匹配到的檔案重名名為xxx.main.js
.pipe(dest("dist/js/")); // 將檔案寫入到 dist/js/ 目錄下
}
清空檔案
安裝
npm install --save-dev gulp-clean
配置
const { series, parallel, src, dest, watch } = require("gulp");
const clean = require("gulp-clean"); // 清空資料夾
// 清空dist資料夾
function cleans() {
// 獲取到dist資料夾下面的所有檔案,進行清空操作
return src(["./dist/*"]).pipe(clean());
}
打包程式碼
新建打包任務
/**
* 打包任務
* 私有任務也可以在 series 組合中使用
* series 是順序執行多個任務
* parallel 是平行執行多個任務
*/
const build = series(cleans, js, html, indexhtml, css, function (cb) {
// 必須要有一個回撥方法
cb();
});
// 公開 build 任務,執行 gulp build 執行打包任務
exports.build = build;
在控制檯執行 gulp build
執行成功後會在根目錄下自動生成一個 dist
資料夾
我們開啟打包好的檔案,可以看到配置的一些規則都是生效的
我們在檔案中直接雙擊開啟 dist/index.html
頁面可以正常的顯示出來,表示路徑的引用也是正確的
完整的開發依賴包
"devDependencies": {
"@babel/core": "^7.14.3",
"browser-sync": "^2.26.14",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-clean": "^0.4.0",
"gulp-csso": "^4.0.1",
"gulp-html-replace": "^1.6.2",
"gulp-htmlmin": "^5.0.1",
"gulp-rename": "^2.0.0",
"gulp-string-replace": "^1.1.2",
"gulp-uglify": "^3.0.2",
"gulp-webserver": "^0.9.1"
}
完整的配置程式碼
const { series, parallel, src, dest, watch } = require("gulp");
const babel = require("gulp-babel"); // 支援es6以及模組化
const uglify = require("gulp-uglify"); // 壓縮js程式碼
const rename = require("gulp-rename"); // 重新命名檔案
const clean = require("gulp-clean"); // 清空資料夾
const csso = require("gulp-csso"); // 壓縮css
const htmlmin = require("gulp-htmlmin"); // 壓縮html
const gulpServer = require("gulp-webserver"); // 啟動專案
const htmlreplace = require("gulp-html-replace"); // 替換檔案引用地址
const replace = require("gulp-string-replace"); // 替換字串
const browserSync = require("browser-sync"); // 啟動專案
const reload = browserSync.reload; // 更新頁面
// 配置壓縮html的規則
const indexOptions = {
removeComments: true, // 清除html註釋
collapseWhitespace: true, // 壓縮html
collapseBooleanAttributes: true, //省略布林屬性的值 <input checked="true"/> -> <input checked />
removeEmptyAttributes: true, // 刪除所有空格作為屬性值 <inpit id=""/> -> <inpit/>
minifyCss: true, // 壓縮頁面中的css
minifyJs: true, // 壓縮頁面中的js
};
// 清空dist資料夾
function cleans() {
// 獲取到dist資料夾下面的所有檔案,進行清空操作
return src(["./dist/*"]).pipe(clean());
}
// 壓縮js
function js() {
// 即使這個任務不需要回撥,但也要有一個預設的回撥方法,也可以return
// cb();
return src("src/public/js/*.js")
.pipe(babel())
.pipe(uglify()) // 壓縮js程式碼
.pipe(replace(/assetApi/g, "https://www.gulpjs.com.cn")) // 替換程式碼中的 "assetApi"
.pipe(rename({ extname: ".min.js" })) // 將匹配到的檔案重名名為xxx.main.js
.pipe(dest("dist/js/")); // 將檔案寫入到 dist/js/ 目錄下
}
// 壓縮打包html
function html() {
return src(["src/view/**/*.html"])
.pipe(htmlmin(indexOptions)) // 使用上面定義的壓縮配置進行壓縮html
.pipe(dest("dist/html/")); // 將檔案寫入到 dist/html/ 目錄下
}
// 單獨處理一下 index.html
function indexhtml() {
return src("src/index.html")
.pipe(
htmlreplace({
// 從註釋標記中獲取要替換的路徑
css: "css/index.css",
js: "js/index.min.js",
})
)
.pipe(htmlmin(indexOptions)) // 使用上面定義的壓縮配置進行壓縮html
.pipe(dest("dist/"));
}
// 壓縮css
function css() {
return src("src/public/css/**/*.css").pipe(csso()).pipe(dest("dist/css"));
}
// 啟動專案
function server() {
browserSync({
notify: false, // 關閉通知,頁面右上角不會出現彈框
port: 3000, // 啟動 3000 埠
server: {
baseDir: ["src"], // 配置根目錄,在這個根目錄下啟動伺服器
},
callbacks: {
// 專案啟動成功後執行的方法
ready: () => {
console.log("開始監控開發資料夾");
// 設定要監控的頁面,當被監控頁面發生變化時執行過載方法
const watcher = watch(["src/**/*.html", "src/**/*.js", "src/**/*.css"]);
// 監聽到變化後執行
watcher.on("change", () => {
// 頁面變化後執行過載方法
reload();
});
},
},
});
}
/**
* 打包任務
* 私有任務也可以在 series 組合中使用
* series 是順序執行多個任務
* parallel 是平行執行多個任務
*/
const build = series(cleans, js, html, indexhtml, css, function (cb) {
// 必須要有一個回撥方法
cb();
});
// 公開 server 任務,執行 gulp server 執行啟動任務
exports.server = server;
// 公開 build 任務,執行 gulp build 執行打包任務
exports.build = build;