HUGO
Menu
GitHub 87548 stars Mastodon

js.Build

Bundle, transpile, tree shake, and minify JavaScript resources.

Syntax

js.Build [OPTIONS] RESOURCE

Returns

resource.Resource

The js.Build function uses the evanw/esbuild package to:

  • Bundle
  • Transpile (TypeScript and JSX)
  • Tree shake
  • Minify
  • Create source maps
{{ 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 }}

Options

targetPath
(string) If not set, the source path will be used as the base target path. Note that the target path’s extension may change if the target MIME type is different, e.g. when the source is TypeScript.
format
(string) The output format. One of: iife, cjs, esm. Default is iife, a self-executing function, suitable for inclusion as a <script> tag.
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 處理壓縮。
loaders
New in v0.140.0
(map) 為給定文件類型配置加載器允許您使用 import 語句或 require 調用加載該文件類型。例如,將 .png 文件擴展名配置為使用數據 URL 加載器意味著導入 .png 文件會為您提供包含該圖像內容的數據 URL。可用的加載器包括 nonebase64binarycopycssdataurldefaultemptyfileglobal-cssjsjsonjsxlocal-csstexttstsx。請參閱 https://esbuild.github.io/api/#loader
inject
(slice) 此選項允許您自動將全局變量替換為來自另一個文件的導入。路徑名必須相對於 assets。請參閱 https://esbuild.github.io/api/#inject
shims
(map) 此選項允許將組件替換為另一個組件。一個常見的用例是在生產環境中從 CDN 加載依賴項(如 React)(使用 shims),但在開發期間使用完整的捆綁 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/client';
target
(string) 語言目標。其中之一:es5es2015es2016es2017es2018es2019es2020es2021es2022es2023es2024esnext。默認為 esnext
platform
New in v0.140.0
(string) 其中之一 browsernodeneutral。默認為 browser。請參閱 https://esbuild.github.io/api/#platform
externals
(slice) 外部依賴項。使用此選項可以修剪您知道永遠不會執行的依賴項。請參閱 https://esbuild.github.io/api/#external
defines
(map) 此選項允許您定義一組在構建時執行的字符串替換。它必須是一個映射,其中每個鍵將被其值替換。
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
drop
New in v0.144.0
(string) 在構建之前編輯源代碼以刪除某些構造:其中之一 debuggerconsole
請參閱 https://esbuild.github.io/api/#drop
sourceMap
(string) 是否從 esbuild 生成 inlinelinkedexternal 源映射。Linked 和 external 源映射將寫入目標目錄,文件名為輸出文件名 + “.map”。當使用 linked 時,sourceMappingURL 也將寫入輸出文件。默認情況下,不創建源映射。請注意,linked 選項是在 Hugo 0.140.0 中添加的。
sourcesContent
New in v0.140.0
(bool) 是否在源映射中包含源文件的內容。默認情況下,這是 true
JSX
(string) 如何處理/轉換 JSX 語法。其中之一:transformpreserveautomatic。默認為 transform。特別是,automatic 轉換是在 React 17+ 中引入的,將自動導入必要的 JSX 輔助函數。請參閱 https://esbuild.github.io/api/#jsx
JSXImportSource
(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);

Import JS code from the assets directory

js.Build has full support for the virtual union file system in Hugo Modules. You can see some simple examples in this test project, but in short this means that you can do this:

import { hello } from 'my/module';

And it will resolve to the top-most index.{js,ts,tsx,jsx} inside assets/my/module in the layered file system.

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

Will resolve to hello3.{js,ts,tsx,jsx} inside assets/my/module.

Any imports starting with . are resolved relative to the current file:

import { hello4 } from './lib';

For other files (e.g. JSON, CSS) you need to use the relative path including any extension, e.g:

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

Any imports in a file outside assets or that does not resolve to a component inside assets will be resolved by ESBuild with the project directory as the resolve directory (used as the starting point when looking for node_modules etc.). Also see hugo mod npm pack. If you have any imported npm dependencies in your project, you need to make sure to run npm install before you run hugo.

Also note the new params option that can be passed from template to your JS files, e.g.:

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

And then in your JS file:

import * as params from '@params';

Hugo will, by default, generate a assets/jsconfig.json file that maps the imports. This is useful for navigation/intellisense help inside code editors, but if you don’t need/want it, you can turn it off.

Node.js dependencies

Use the js.Build function to include Node.js dependencies.

Any imports in a file outside assets or that does not resolve to a component inside assets will be resolved by esbuild with the project directory as the resolve directory (used as the starting point when looking for node_modules etc.). Also see hugo mod npm pack. If you have any imported npm dependencies in your project, you need to make sure to run npm install before you run hugo.

The start directory for resolving npm packages (aka. packages that live inside a node_modules directory) is always the main project directory.

If you’re developing a theme/component that is supposed to be imported and depends on dependencies inside package.json, we recommend reading about hugo mod npm pack, a tool to consolidate all the npm dependencies in a project.

Examples

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

Or with options:

{{ $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>

Last updated: January 1, 0001
Improve this page