點燈坊

失くすものさえない今が強くなるチャンスよ

整合 Hugo 與 Alpine

Sam Xiao's Avatar 2024-01-23

Alpine 特別適合後端有自己 Template Engine 的使用場景,Hugo 雖然為 SSG,但因為使用了 Go Template,事實上與後端類似,因此也適合 Alpine。

Version

Hugo 0.121.2
Alpine 3.13.4

New Site

$ hugo new site hugo-alpine --format json
  • hugo new site : 以預設骨架建立 Hugo 站台
  • –format json : 以 JSON 格式作為 Hugo 設定檔

Install Alpine

$ npm install alpinejs
  • 使用 NPM 安裝 Alpine

WebStorm

alpine001

  • 安裝 Alpine.js Support plugin,支援 Alpine 的 intellisense 與 attribute 辨識

Module Mounts

hugo.json

{
   "baseURL": "https://example.org/",
   "languageCode": "en-us",
   "title": "My New Hugo Site",
   "module": {
      "mounts": [
         {
            "source": "node_modules/alpinejs/dist/cdn.js",
            "target": "static/js/alpine.js"
         }
      ]
   }
}

Line 5

"module": {
  "mounts": [
    {
      "source": "node_modules/alpinejs/dist/cdn.js",
      "target": "static/js/alpine.js"
    }
  ]
}
  • node_modules 目錄下的 Alpine mount 到 static 目錄下,只是邏輯上的 mount,並不是 copy 到 static 目錄下
  • 因為在 static 目錄下的 JavaScript 可直接使用最為方便,因此選擇 mount 到 static 目錄下
  • 雖然在 static 目錄下看不到 Alpine,但最後會將 Alpine publish 到 public 目錄下

Layout

layouts/index.html

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="js/alpine.js" defer></script>
    {{ $title := "Alpine Lab" }}
    <title>{{ $title }}</title>
  </head>
  <body>
    <div>{{ $title }}</div>
    <div x-data="{ count: 0 }">
      <button x-on:click="count++">+</button>
      <div x-text="count"></div>
    </div>
  </body>
</html>

Line 6

<script src="js/alpine.js" defer></script>
  • 引用在 static/js 目錄下的 alpine.js

Line 7

{{ $title := "Alpine Lab" }}
<title>{{ $title }}</title>
  • 定義 Go template 變數
  • 顯示 Go template 變數

Line 12

<div x-data="{ count: 0 }">
  <button x-on:click="count++">+</button>
  <div x-text="count"></div>
</div>
  • x-data:定義 Alpine 變數
  • x-on:click:click event
  • x-text:顯示 Alpine 變數

使用 x-text 可避免與 Go Template 的 delimiter 衝突

Conclusion

  • Alpine 的美感就是將 JavaScript 融合在 HTML 內,這對 Hugo 這種幾乎不使用 JavaScript,而以 HTML 為主體的風格特別合適
  • 使用 Module Mount 可簡單將 node_modules 下的 Petite-vue mount 到 static 目錄下,如此可繼續使用 NPM 管理 Petite-vue 版本,不必再手動將 Petite-vue 複製到 static 目錄下,此方法也適用於其他 NPM 套件
  • Alpine 不再糾結於 Go Template 的 delimiter ,直接使用 v-text 避開