ASSET MANAGEMENT

js.Build

使用方法

任何 JavaScript 資源檔案都可以使用 js.Build 進行轉譯和「樹搖」(tree shake)。此函數的參數可以是檔案路徑字串或下列選項的字典。

選項

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) 此選項允許您用另一個元件替換某個元件。常見的用例是當在生產環境中使用 shims 從 CDN 加載像是 React 這類的依賴,而在開發環境中則運行完整的 node_modules 依賴:
{{ $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';
target
(string) 語言目標。
可選值:es5es2015es2016es2017es2018es2019es2020esnext
預設值為 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 和 node 模組中讀取,並合併成輸出的來源映射。預設情況下,來源映射不會被創建。
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 模組 中的虛擬聯合檔案系統。您可以在這個 測試專案 中看到一些簡單範例,簡而言之,這意味著您可以這樣做:

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 檔案來映射這些導入。這對於程式碼編輯器中的導航/智能提示很有幫助,但如果您不需要或不想要,您可以 關閉它

在 package.json / node_modules 中包含依賴

任何在 /assets 外部的檔案導入,或者無法解析為 /assets 中元件的導入,將由 ESBuild 使用 專案目錄 作為解析目錄(即查找 node_modules 等的起始點)進行解析。詳情請參見 hugo mod npm pack。如果您的專案中有導入的 npm 依賴,請確保在執行 hugo 前運行 npm install

解析 npm 套件的起始目錄始終是專案的根目錄。

範例

{{ $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" | js.Build $opts }}
<script src="{{ $built.RelPermalink }}" defer></script>