HTML在最後會載入 JavaScript,也是各 Template 都會重複使用之處,可將其抽成 Partial 方便維護。
Version
Hugo 0.147.8
JavaScript
assets/js/main.js
import { initHome } from './_home'
import { initSingle } from './_single'
import { initList } from './_list'
import { initAbout } from './page/_about'
document.addEventListener('DOMContentLoaded', () => {
console.log('Hello from main.js!')
initHome()
initSingle()
initList()
initAbout()
})
- 負責引用其他 JavaScript,本身不寫任何邏輯
JavaScript Partial
layouts/_partials/js.html
{{ with resources.Get "js/main.js" }}
{{ $opts := dict
"minify" (not hugo.IsDevelopment)
"sourceMap" (cond hugo.IsDevelopment "external" "")
"targetPath" "js/main.js"
}}
{{ with . | js.Build $opts }}
{{ if hugo.IsDevelopment }}
<script src="{{ .RelPermalink }}"></script>
{{ else }}
{{ with . | fingerprint }}
<script
src="{{ .RelPermalink }}"
integrity="{{ .Data.Integrity }}"
crossorigin="anonymous"></script>
{{ end }}
{{ end }}
{{ end }}
{{ end }}
- 負責載入 JavaScript
Line 1
{{ with resources.Get "js/main.js" }}
{{ end }}
resources.Get():從assets目錄取得main.jswith():若js/main.js存在,將目前 context切到所回傳物件繼續 pipe
Line 2
{{ $opts := dict
"minify" (not hugo.IsDevelopment)
"sourceMap" (cond hugo.IsDevelopment "external" "")
"targetPath" "js/main.js"
}}
dict():整理js.Build()所需 map 參數minify:開發模式時false,生產模式時則truesourceMap:開發模式時產生,生產模式時不產生targetPath:最終產出為js/main.js
Line 7
{{ with . | js.Build $opts }}
{{ end }}
js.Build():將目前 context傳入js.Build $opts目前 context是js/main.js物件js.Build $opts為 partial function,因此可將.傳入
with():若js.Build()成功,則將目前 context切到回傳物件繼續 pipe
Line 8
{{ if hugo.IsDevelopment }}
<script src="{{ .RelPermalink }}"></script>
開發模式 下處理 JavaScript:
RelPermalink:直接從目前 context取得其相對路徑目前 context是js.Build()回傳物件
Line 10
{{ else }}
{{ with . | fingerprint }}
<script
src="{{ .RelPermalink }}"
integrity="{{ .Data.Integrity }}"
crossorigin="anonymous"></script>
{{ end }}
{{ end }}
生產模式 下處理 JavaScript:
fingerprint():將 JavaScript 檔名加上 hash,避免被連覽器 cache目前 context是js.Build()回傳物件
with():若fingerprint()成功,則將目前 context切到回傳物件繼續 pipeRelPermalink:直接從目前 context取得其相對路徑Data.Integrity:提供 SRI,用來讓瀏覽器驗證資源內容是否被竄改,需搭配crossorigin="anonymous"目前 context是fingerprint()回傳物件
Baseof Template
layouts/baseof.html
<!doctype html>
<html lang="en">
<head>
{{ partial "css.html" . }}
</head>
<body>
{{ block "main" . }}{{ end }}
{{ partial "js.html" . }}
</body>
</html>
- 所有 template 基礎的
baseof.html
Line 8
{{ partial "js.html" . }}
- 在
<body>內引用jspartial
Conclusion
- JavaScript 要處理的東西看似簡單,這原本都要靠 Gulp、Webpack、Vite 之類工具處理,但這些 Hugo 都已經內建,只需 Pipe 即可,可將這些處理過程整合在
jsPartial 內 - 之所以要朝狀使用
with(),因為每個 Function 執行會成功或失敗,只有成功後才會將目前 Context切到回傳物件繼續 Pipe - 此段處理 JavaScript 流程摘自 Hugo 官網,極具參考價值,是非常優秀的 Go template 寫法