前言
此篇將紀錄從接觸 Gulp 開始到後來能夠獨立開發專案所需 Gulp 環境的學習總結。前面會先把之前所遇到的坑做一個解決辦法補充,比如透過 Babel 編譯後,require 語法無法在 Browser 運行等問題,以及使用 gulp-rename 套件後,該如何連同 HTML 相關的引用路徑做一個響應變動等等,最後也會提供我最為常用的 Gulp 開發環境,供有興趣的開發者快速導入現有專案。
筆記重點
- 本系列文章
- 踩坑 - require 語法無法在 Browser 運行
- 踩坑 - HTML 引用路徑該如何做響應變動
- 總結 - Gulp 常用開發環境
本系列文章
- Gulp 前端自動化 - 環境安裝與執行
- Gulp 前端自動化 - 編譯 Sass/SCSS
- Gulp 前端自動化 - 編譯 Pug
- Gulp 前端自動化 - 使用 Babel 編譯 ES6
- Gulp 前端自動化 - PostCSS 與 Autoprefixer
- Gulp 前端自動化 - 生成 SourceMap 映射文件
- Gulp 前端自動化 - Browsersync 瀏覽器同步測試工具
- Gulp 前端自動化 - 自動清除檔案與資料夾
- Gulp 前端自動化 - 壓縮 HTML、CSS、JavaScript 代碼
- Gulp 前端自動化 - 壓縮並優化圖片
- Gulp 前端自動化 - Minimist 命令行參數解析工具
- Gulp 前端自動化 - 替換 Stream 中的檔案名稱
- Gulp 前端自動化 - 導入 Bootstrap 客製並編譯它
- Gulp 前端自動化 - CommonJS 模組化設計
- Gulp 前端自動化 - 升級至 Gulp 4 完整說明
- Gulp 前端自動化 - 使用 ES6 Module 撰寫 Gulpfile
踩坑 - require 語法無法在 Browser 運行
在之前的 使用 Babel 編譯 ES6 文章中,有提到關於 @babel/runtime 與 @babel/polyfill 的使用方式,解決 Babel 預設只能處理 Syntax 的問題,但此時也就衍發了另一個問題,那就是編譯後檔案中的 require 語法是無法在 Browser 運行的,require 語法屬於 Node.js 的模組化語法,瀏覽器不兼容此語法,當初卡了這個問題好久,最後找到了 Webpack-stream 這一個套件,透過打包的方式解決此問題,讓我們直接來使用它吧!
初始專案結構:
1 | gulp-demo/ |
套件連結:gulp-babel、@babel/runtime-corejs3、@babel/plugin-transform-runtime
安裝 Babel:
1 | $ npm install gulp-babel @babel/core @babel/preset-env |
安裝 Plugins:
1 | $ npm install @babel/runtime-corejs3 @babel/plugin-transform-runtime |
撰寫 ES6+ 版本代碼:
1 | const arr = [1, 2, 3, 4, 5]; |
載入並使用 gulp-babel:
1 | const gulp = require('gulp'); |
新增並配置 .babelrc
:
1 | { |
執行指定任務:
1 | $ gulp |
編譯結果:
1 | ; |
瀏覽器運行結果(報錯):
Uncaught ReferenceError: require is not defined
很明顯的 require 語法是無法在瀏覽器上運行的,通常都得透過像是 Webpack 的打包工具,將代碼轉換為適合瀏覽器的可用格式才能成功運行,事實上,Webpack-stream 就是 Webpack 用來與 Gulp 搭配的集成工具,透過 Webpack 的配置方式即可完成操作,讓我們先從安裝開始。
1 | $ npm install webpack-stream babel-loader |
Webpack 本身是 Webpack-stream 相依套件,我們只需下載 Webpack-stream 即可,另外也必須下載 babel-loader 作為編譯的預處理器。
載入並使用 webpack-stream:
1 | const gulp = require('gulp'); |
執行指定任務:
1 | $ gulp |
瀏覽器運行結果(成功):
[ 4, 5 ]
相信熟悉 Webpack 的人對於上面配置應該再清楚不過了,事實上,Webpack-stream 就是用來導入 Webpack 的 Gulp 工具,當 Webpack 所在的 Stream 處理完成時,即進入下一個 pipe 節點,由於 babel-loader 的使用,我們也不需要使用 gulp-babel 了,Webpack 與 Gulp 的結合就是採用此方法來完成,有興趣的可以在進行研究,之後也會推出一系列的 Webpack 文章,敬請期待。
踩坑 - HTML 引用路徑該如何做響應變動
在我們之前介紹到 minimist 命令行參數解析工具時,有提到關於 development 與 production 環境的差別,當時是以 gulp-clean-css 與 gulp-rename 套件去做示例,假設當前為 production 環境,需使用 gulp-clean-css 壓縮代碼並且使用 gulp-rename 更改名稱為 .min.css
檔,此時當我們開啟 index.html 檔案時,會發現 js 與 css 都沒有被載入進來,因為此環境編譯後檔案是不存在 .js
或 .css
檔案的,檔名通通都改成 .min
了,可能會有人手動去更改編譯前的引用路徑,但這有違使用自動化工具的目的,這時我們可以使用 gulp-html-replace 套件來解決這一個問題,讓我們直接開始吧!
初始專案結構:
1 | gulp-demo/ |
套件連結:del、gulp-clean-css、gulp-if、gulp-rename、minimist、gulp-html-replace
相關套件:
1 | $ npm install del gulp-clean-css gulp-if gulp-rename minimist |
主要套件:
1 | $ npm install gulp-html-replace |
載入並使用 gulp-html-replace:
1 | const gulp = require('gulp'); |
開啟 ./source/index.html
並輸入以下註解:
1 | <!-- build:css --> |
在 production 環境執行指定任務:
1 | $ gulp --env production |
編譯結果:
1 | <link rel="stylesheet" href="css/all.min.css" /> |
從上面結果可得知,使用 gulp-html-replace 套件確實可以響應引用路徑,它的原理其實很簡單,如下範例:
index.html
:
1 |
|
gulpfile.js
:
1 | htmlreplace({ |
編譯結果:
1 |
|
使用 gulp-html-replace 的關鍵在於 <!-- build:name -->
註解中的 name 需要與 htmlreplace
中的 key
相互對應,告知此區塊開始進行處理,並且加入<!-- endbuild -->
告知此處結束處理,這邊要注意的是此操作是以塊的方式進行處理,如同上面範例的 js 區塊,不管有幾行的代碼,通通都會被取代成相對應的代碼,搭配 gulp-if 等相關套件即可解決 gulp-rename 後引用路徑錯誤的問題,達到真正的自動化效果。
總結 - Gulp 常用開發環境
安裝套件:
1 | $ npm i gulp-babel gulp-sass gulp-postcss gulp-clean-css gulp-htmlmin gulp-imagemin gulp-uglify gulp-rename gulp-html-replace gulp-sourcemaps gulp-if browser-sync minimist webpack-stream del |
Babel 相關套件:
1 | $ npm i @babel/core @babel/preset-env @babel/plugin-transform-runtime @babel/runtime-corejs3 |
PostCSS 相關套件:
1 | $ npm i autoprefixer |
Webpack-stream 相關套件:
1 | $ npm i babel-loader |
新增並配置 gulpfile.js
:
1 | const gulp = require('gulp'); |
新增並配置 .babelrc
:
1 | { |
新增並配置 postcss.config.js
:
1 | module.exports = { |
新增並配置 .browserslistrc
:
1 | last 2 version |
學到了這邊,看到很多相關文章都在探討 Webpack 將會取代 Gulp 成為主流,但我認為兩者本質上是不同的東西,何來比較?各有各的優缺點,雙方是互補的,在上面範例中,由於 require 無法運行在瀏覽器上面,我也是導入 Webpack-stream 用以打包代碼,並沒有誰好誰不好的說法,Gulp 適合小型開發,配置簡單,輕鬆上手,而 Wepack 適合開發稍有規模的專案,尤其是 SPA (單頁式應用),對於筆者來講,兩個工具都把它學起來,就沒有這麼多的麻煩了,之後也會有一系列的 Webpack 文章,敬請期待。