各位好,我在嘗試將網頁所有使用到的 JS 都包裝且壓縮到同一個檔案(main.js)中以減少 HTTP Request,在過程中腳本載入的先後順序出現問題讓網頁無法如期望運作,因此想請教這方面的問題。
HUGO Static Site Generator 中的 ESBuild JS Bundler,以及引用一些 JS 框架如 Alpine.js、Photoswipe、MagicGrid......。
之後我退一步重新讀過 Hugo Pipeline 和其他如何在 HUGO 中 Bundle assets 的文章,例如
Hugo Pipes Revolution
主要是最後那一篇
了解在 HUGO 中怎麼抓取 JS 檔案再最後合併起來,使用 .Get .Concat 之類很簡單的方式,然後使用原生 JS 的 Import 導入 Node_Module 中的文件
ESBuild、JS Module 不是很熟,還要找時間惡補一下。
{{/* Javascript bundling */}}
<!-- Get files -> Global -->
{{ $alpine := resources.Get "js/global/alpine.js" }}
{{ $main := resources.Get "js/global/debug.js" }}
{{ $navbarMain := resources.Get "js/global/navbarMain.js" }}
{{ $lazyVideo := resources.Get "js/global/lazyVideo.js" }}
<!-- Get files -> Projects Page -->
{{ $magicGrid := resources.Get "js/projects/magicGrid.js" }}
<!-- Get Alpine Module -->
{{ $toastNotification := resources.Get "js/alpineModule/toastNotification.js" }}
{{ $everyJs := (slice $alpine $main $navbarMain $lazyVideo $magicGrid $toastNotification) }}
{{ $js := $everyJs | resources.Concat "js/global.js" }}
{{ $js = $js | js.Build }}
{{ if hugo.IsProduction }}
{{ $js = $js | js.Build | minify | resources.Fingerprint "sha256" }}
{{ end }}
{{/* Link JS */}}
<script type="module" src="{{ $js.RelPermalink }}" integrity="{{ $js.Data.Integrity }}"></script>
以上是我的 HUGO Javascript 打包的方式,概念差不多就是這樣。
將 JS 框架、內容都打包壓縮後放置在 <head>
中,使用 defer 希望「解析 HTML 過程中一邊下載 JS 並在 HTML 跑完後執行」
import Alpinejs from "alpinejs/dist/cdn.min.js";
function toastNotification() {
return {
open: false,
title: "Toast Tiatle",
message: "Toast message",
success: false,
openToast() {
this.open = true
setTimeout(() => {
this.open = false
}, 3000)
}
}
}
寫了一個 Function 使用到 alpine.js 同樣打包在最終的(main.js)中,如上。但卻只跳出錯誤並無法運作。
但如果把這個 toastNotification() 做為 InlineScript 導入在 HTML 中的話在不管哪裡都能順利運作,如同下圖。
我就頭痛了,為什麼沒辦法把所有JS都壓在一個檔案之中?
我想要更進一步整理 main.js 的載入順序,把框架和自己寫的一些設定分離檔案做整理,在最後 import 進來,但不曉得原因,好像外連的檔案並不知道我的框架內容(? 我猜是這樣的問題)。
不曉得一般使用框架和設定內容是如何處理整理的?
// My own scripts
import { lazyVideo } from "js/lazyVideo.js";
import { navbarMain } from "js/navbarMain.js";
// Frameworks
import MagicGrid from "magic-grid/dist/magic-grid.esm.js";
import PhotoSwipeLightbox from "photoswipe/dist/photoswipe-lightbox.esm.min.js";
import PhotoSwipe from "photoswipe/dist/photoswipe.esm.min.js";
import Alpinejs from "alpinejs/dist/cdn.min.js";
// Frameworks setting
import toastNotification form "js/toastNotification.js";
import MagicGridConfig form "js/MagicGridConfig.js";
import PhotoSwipeConfig form "js/PhotoSwipeConfig.js";
以上是我理想的(main.js)樣貌,但無法運作。
感謝各位耐心解讀我的問題!