靜態網站導入 webpack 進行重構

這次將 ACGN股市歷史博物館1 的頁面,從原先只有單純的 HTML、CSS和JavaScript,逐一導入 webpack 和 loader 套件,鋪設基礎建設後,使其更利於未來的開發與維護。

導入前的專案目錄截圖

導入前的專案目錄截圖,commit 連結

這次執行過程,主要是受到這篇文章2的啟發,同時,也參考該篇文章的操作流程,進行專案導入 webpack 的處理,也藉由操作的過程,更加熟悉 webpack 生態系。以下,將依序介紹這次導入的相關工具,以及他們的使用場景。

Yarn

專案套件管理的基礎,在後續處理專案安全漏洞問題時,使用 Yarn 提供的 Selective dependency resolutions3 功能,在 package.json 檔裡設定 resolution,有限地解決部份安全漏洞。

webpack 5

專案打包工具,將專案依照設定,打包成滿足特定情境需求的版本,由於 webpack 5 有提供 Asset Modules4 的功能,不用再像以往,需要使用 raw-loader, url-loader 和 file-loader 之類。

.babel-loader

將 ES6+ 的 JavaScript 原始碼轉譯成 ES5

.css-loader、mini-css-extract-plugin

前者是處理在 JavaScript 檔案中,import CSS 檔案的載入處理。後者是將載入後的 CSS 內容,輸出成獨立的檔案。

.html-webpack-plugin

將初始的 index.html 轉為輸出成目標 HTML 的模板使用,該 plugin 預設使用 EJS 的模板語言,藉由在模板中撰寫模板語法,減少在重複 DOM 元素上的重複作業,提昇開發效率。

.favicon-webpack-plugin

使用該 plugin 來處理 favicon 的產生與插入到目標 HTML 的任務。

.Asset Modules

這次是用 asset/resource 來處理 JavaScript 檔案中,動態載入的圖片,確保輸出的結果能夠確實存取到這些圖片。

.webpack-dev-server

供專案開發時使用的網頁伺服器,並利用其 HMR (5) 特性,讓程式碼在被修改後,能夠立即在網頁上呈現,進而提昇開發效率。

browserlist

使用該套件統一管理專案中,需要使用目標瀏覽器資訊套件的設定。

PostCSS

將輸入的 CSS 檔案,按照設定的任務依序處理,輸出處理後的 CSS 內容。

.autoprefixer

依照 package.json 內的 browserlist 設定,對 CSS style 加上瀏覽器專有的 prefix。

.PurgeCSS

讀取專案原始碼並進行分析,移除未被使用的 CSS style,以達成對 CSS 的瘦身。

.CSSNANO

對 CSS 進行壓縮,以達成最後輸出的 CSS 檔案大小最小化。

ESLint、babel-eslint

依照設定的規則,檢查 JavaScript 原始碼的程式語法,並提出修改建議,以達成程式碼美化與風格上的統一。規劃未來將 babel-eslint 替換成 @babel/eslint-parser6。

Stylelint

針對 CSS 的原始碼程式語法與風格檢查工具。

導入後的專案目錄截圖

導入後的專案目錄截圖,commit 連結

原先根目錄底下的 index.html 搬移到 src 目錄底下管理,同時,assets 目錄底下的 JavaScript 和 CSS 的程式碼,以及 favicon 檔案都也搬移到 src 目錄底下管理。又 images 底下的圖片檔也搬移到 src 目錄底下管理。專案根目錄多了 public 和 dist 目錄,前者用作開發時 devServer 使用,後者用作部屬版本的輸出目錄使用。

新版本的專案要部屬前,先在正式環境上,參考教學78來修改 NGINX 設定,使其能夠同時服務新舊兩個版本,以利做 A/B 測試做對照。

舊版本的測試結果 (WebPageTest)

舊版本的測試結果,詳細資訊

新版本的測試結果 (WebPageTest)

新版本的測試結果,詳細資訊

舊版本的測試結果 (GTmetrix)

舊版本的測試結果,詳細資訊

新版本的測試結果 (GTmetrix)

新版本的測試結果,詳細資訊

基本上網頁在載入的表現上差異不大,符合預期。


第一階段的工作基本上到這邊就結束了,接下來建立在這個基礎建設上,對網站進行重構,使其呈現效果與使用者操作上更加友好。

首先,導入 image-webpack-loader,來處理以往圖片壓縮處理人工操作的部份,在輸入檔案總共 62 MB 的情況下,原先人工操作的部份可以壓縮到 24 MB,使用該 plugin 來處理的話,則會壓縮到 32 MB,考量到自動化以及圖片並非全部一次載入,plugin 帶來的優劣還是可以接受的。

接著,導入 Tailwind CSS9 與 Flowbite10,讓 CSS style 在撰寫與管理上更加清楚明瞭,並善用 html-webpack-loader 與 EJS11 語法對 index.html 進行重構,最後,參考教學12撰寫 image lazy-loading 處理。

重構完成後的網站,帶來以下好處:

  • 由於網站清單和圖片清單資料都抽出來獨立成檔案來管理,未來在新增對應資訊上的處理更加便捷。
  • 網站清單的呈現與操作在桌面端與移動端上更加友好。
  • 圖片可以完整的呈現,點擊圖片也能開啟對應賽季公司的詳細資訊頁。
  • 圖片顯示區塊有要載入圖片的主要顏色13作墊底顯示。
  • 圖片顯示區塊有載入動畫,能讓使用者更清楚圖片正在載入狀態。

最終的專案目錄截圖

最終的專案目錄截圖

註腳

  1. ACGN股市歷史博物館 ↩

  2. How to Bundle a Simple Static Site Using Webpack ↩

  3. Selective dependency resolutions | Yarn ↩

  4. Asset Modules ↩

  5. Hot Module Replacement | webpack ↩

  6. The State of babel-eslint | BABEL ↩

  7. A/B testing with NGINX in under 40 lines of code | freeCodeCamp ↩

  8. Performing A/B Testing with NGINX and NGINX Plus ↩

  9. Tailwind CSS ↩

  10. Flowbite ↩

  11. EJS ↩

  12. The Complete Guide to Lazy Loading Images | CSS-TRICKS ↩

  13. 主要顏色的分析工具 ↩

留言