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
- (
map
或slice
) 可以在您的 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
,es2020
或esnext
。預設為esnext
。 externals
- (
slice
) 外部依賴。使用此選項來修剪您知道不會執行的依賴。詳情請見 https://esbuild.github.io/api/#external defines
- (
map
) 允許在構建時進行字串替換的設置。應為一個字典,每個鍵將會被其對應的值所替換。
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
format
- (
string
) 輸出格式。選項有:iife
、cjs
、esm
。預設為iife
,即自執行函數,適合包含在<script>
標籤中。 sourceMap
- (
string
) 是否從 esbuild 生成inline
或external
來源地圖。外部來源地圖將寫入目標檔案並附加“.map”副檔名。可以從 js.Build 和節點模組讀取輸入來源地圖,並將其與輸出來源地圖結合。預設情況下不會創建來源地圖。 - JSX New in v0.124.0
- (
string
) 如何處理/轉換 JSX 語法。選項有:transform
、preserve
、automatic
。預設為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
JSX
和 JSXImportSource
的組合對於想使用非 React 的 JSX 庫(例如 Preact)非常有幫助,例如:
{{ $js := resources.Get "js/main.jsx" | js.Build (dict "JSX" "automatic" "JSXImportSource" "preact") }}
如此一來,您可以使用 Preact 元件和 JSX,而不必每次都手動匯入 h
和 Fragment
:
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';
對於其他檔案(例如 JSON
、CSS
),您需要使用相對路徑並包括副檔名,例如:
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" | ... }}