js.Build

js.Build 函數使用 evanw/esbuild 套件來進行以下操作:

  • 綁定
  • 轉譯(支援 TypeScript 和 JSX)
  • 樹搖
  • 壓縮
  • 建立來源地圖
{{ with resources.Get "js/main.js" }}
  {{ if hugo.IsDevelopment }}
    {{ with . | js.Build }}
      <script src="{{ .RelPermalink }}"></script>
    {{ end }}
  {{ else }}
    {{ $opts := dict "minify" true }}
    {{ with . | js.Build $opts | fingerprint }}
      <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
    {{ end }}
  {{ end }}
{{ end }}

選項

targetPath
(string) 若未設定,將使用來源路徑作為目標路徑。
請注意,若目標 MIME 類型不同(例如來源是 TypeScript),目標路徑的副檔名可能會改變。
params
(mapslice) 可以在您的 JS 檔案中作為 JSON 匯入的參數,例如:
{{ $js := resources.Get "js/main.js" | js.Build (dict "params" (dict "api" "https://example.org/api")) }}

接著在您的 JS 檔案中:

import * as params from '@params';

請注意,這僅適用於小型資料集(例如配置設定)。對於較大的資料,請將檔案放到 /assets 資料夾並直接匯入。

minify
(bool) 讓 js.Build 處理壓縮。
inject
(slice) 此選項允許您自動將全域變數替換為從其他檔案匯入的內容。路徑名稱必須是相對於 assets 的位置。詳細資訊請見 https://esbuild.github.io/api/#inject
shims
(map) 此選項允許您將某些元件替換為其他元件。常見的用途是當開發環境中加載完整的 node_modules 依賴,而在生產環境中從 CDN 載入像是 React 的依賴(透過 shims):
{{ $shims := dict "react" "js/shims/react.js"  "react-dom" "js/shims/react-dom.js" }}
{{ $js = $js | js.Build dict "shims" $shims }}

以下是 shim 檔案的範例:

// js/shims/react.js
module.exports = window.React;
// js/shims/react-dom.js
module.exports = window.ReactDOM;

在這個設定下,這些匯入應該可以在兩種情況下正常運作:

import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
target
(string) 語言目標。選項有:es5, es2015, es2016, es2017, es2018, es2019, es2020esnext。預設為 esnext
externals
(slice) 外部依賴。使用此選項來修剪您知道不會執行的依賴。詳情請見 https://esbuild.github.io/api/#external
defines
(map) 允許在構建時進行字串替換的設置。應為一個字典,每個鍵將會被其對應的值所替換。
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
format
(string) 輸出格式。選項有:iifecjsesm。預設為 iife,即自執行函數,適合包含在 <script> 標籤中。
sourceMap
(string) 是否從 esbuild 生成 inlineexternal 來源地圖。外部來源地圖將寫入目標檔案並附加“.map”副檔名。可以從 js.Build 和節點模組讀取輸入來源地圖,並將其與輸出來源地圖結合。預設情況下不會創建來源地圖。
JSX New in v0.124.0
(string) 如何處理/轉換 JSX 語法。選項有:transformpreserveautomatic。預設為 transform。需要注意的是,automatic 轉換是在 React 17+ 中引入的,並會自動匯入所需的 JSX 幫助函數。詳情請見 https://esbuild.github.io/api/#jsx
JSXImportSource New in v0.124.0
(string) 要使用的庫來自動匯入其 JSX 幫助函數。僅當 JSX 設定為 automatic 時有效。指定的庫必須通過 npm 安裝並暴露某些導出。詳情請見 https://esbuild.github.io/api/#jsx-import-source

JSXJSXImportSource 的組合對於想使用非 React 的 JSX 庫(例如 Preact)非常有幫助,例如:

{{ $js := resources.Get "js/main.jsx" | js.Build (dict "JSX" "automatic" "JSXImportSource" "preact") }}

如此一來,您可以使用 Preact 元件和 JSX,而不必每次都手動匯入 hFragment

import { render } from 'preact';

const App = () => <>Hello world!</>;

const container = document.getElementById('app');
if (container) render(<App />, container);

從 /assets 匯入 JS 代碼

js.Build 完全支援 Hugo Modules 中的虛擬聯合檔案系統。您可以在這個 測試專案 中查看一些簡單的範例,簡單來說,這意味著您可以這樣做:

import { hello } from 'my/module';

它將會解析為 assets/my/module 資料夾中最上層的 index.{js,ts,tsx,jsx}

import { hello3 } from 'my/module/hello3';

會解析為 assets/my/module/hello3.{js,ts,tsx,jsx}

任何以 . 開頭的匯入路徑都會相對於當前檔案解析:

import { hello4 } from './lib';

對於其他檔案(例如 JSONCSS),您需要使用相對路徑並包括副檔名,例如:

import * as data from 'my/module/data.json';

任何不在 /assets 資料夾內或無法解析為 /assets 資料夾內元件的匯入,將由 ESBuild 使用 專案目錄 來解析(即使用專案目錄作為解析 node_modules 等的起點)。另外請參見 hugo mod npm pack。如果您的專案中有任何匯入的 npm 依賴,請確保在執行 hugo 之前先執行 npm install

還請注意新增加的 params 選項,可以從模板傳遞至 JS 檔案,例如:

{{ $js := resources.Get "js/main.js" | js.Build (dict "params" (dict "api" "https://example.org/api")) }}

接著在您的 JS 檔案中:

import * as params from '@params';

Hugo 預設會生成 assets/jsconfig.json 檔案來映射這些匯入。這對於代碼編輯器中的導航和自動完成很有幫助,但如果您不需要,您可以 關閉這個功能

Node.js 依賴

使用 js.Build 函數來包含 Node.js 依賴。

任何位於 /assets 以外的檔案,或無法解析為 /assets 中元件的匯入,將由 esbuild 使用 專案目錄 來解析(即使用專案目錄作為解析 node_modules 等的起點)。另外請參見 hugo mod npm pack。如果您的專案中有任何匯入的 npm 依賴,請確保在執行 hugo 之前先執行 npm install

解析 npm 套件的起始目錄(即存放 node_modules 資料夾的目錄)始終是專案的根目錄。

範例

{{ $built := resources.Get "js/index.js" | js.Build "main.js" }}

或者帶有選項:

{{ $externals := slice "react" "react-dom" }}
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}

{{ $opts := dict "targetPath" "main.js" "externals" $externals "defines" $defines }}
{{ $built := resources.Get "scripts/main.js" | ... }}