mirror of
https://github.com/gohugoio/hugo.git
synced 2025-04-29 23:20:49 +03:00
Merge commit 'e9fbadacc3
'
This commit is contained in:
commit
0fc86783ee
33 changed files with 608 additions and 443 deletions
|
@ -3,8 +3,9 @@ title: js.Babel
|
|||
description: Compiles the given JavaScript resource with Babel.
|
||||
categories: []
|
||||
keywords: []
|
||||
weight: 100
|
||||
action:
|
||||
aliases: [babel]
|
||||
aliases: [babel,/hugo-pipes/babel/]
|
||||
related:
|
||||
- functions/js/Build
|
||||
- functions/resources/Fingerprint
|
||||
|
|
331
docs/content/en/functions/js/Batch.md
Normal file
331
docs/content/en/functions/js/Batch.md
Normal file
|
@ -0,0 +1,331 @@
|
|||
---
|
||||
title: js.Batch
|
||||
description: Build JavaScript bundle groups with global code splitting and flexible hooks/runners setup.
|
||||
weight: 50
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
aliases: []
|
||||
related:
|
||||
- functions/js/Build
|
||||
- functions/js/Babel
|
||||
- functions/resources/Fingerprint
|
||||
- functions/resources/Minify
|
||||
returnType: js.Batcher
|
||||
signatures: ['js.Batch [ID]']
|
||||
toc: true
|
||||
---
|
||||
|
||||
{{% note %}}
|
||||
For a runnable example of this feature, see [this test and demo repo](https://github.com/bep/hugojsbatchdemo/).
|
||||
{{% /note %}}
|
||||
|
||||
The Batch `ID` is used to create the base directory for this batch. Forward slashes are allowed. `js.Batch` returns an object with an API with this structure:
|
||||
|
||||
* [Group]
|
||||
* [Script]
|
||||
* [SetOptions]
|
||||
* [Instance]
|
||||
* [SetOptions]
|
||||
* [Runner]
|
||||
* [SetOptions]
|
||||
* [Config]
|
||||
* [SetOptions]
|
||||
|
||||
|
||||
## Group
|
||||
|
||||
The `Group` method take an `ID` (`string`) as argument. No slashes. It returns an object with these methods:
|
||||
|
||||
|
||||
#### Script
|
||||
|
||||
The `Script` method takes an `ID` (`string`) as argument. No slashes. It returns an [OptionsSetter] that can be used to set [script options] for this script.
|
||||
|
||||
```go-html-template
|
||||
{{ with js.Batch "js/mybatch" }}
|
||||
{{ with .Group "mygroup" }}
|
||||
{{ with .Script "myscript" }}
|
||||
{{ .SetOptions (dict "resource" (resources.Get "myscript.js")) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
`SetOptions` takes a [script options] map. Note that if you want the script to be handled by a [runner], you need to set the `export` option to match what you want to pass on to the runner (default is `*`).
|
||||
|
||||
#### Instance
|
||||
|
||||
The `Instance` method takes two `string` arguments `SCRIPT_ID` and `INSTANCE_ID`. No slashes. It returns an [OptionsSetter] that can be used to set [params options] for this instance.
|
||||
|
||||
```go-html-template
|
||||
{{ with js.Batch "js/mybatch" }}
|
||||
{{ with .Group "mygroup" }}
|
||||
{{ with .Instance "myscript" "myinstance" }}
|
||||
{{ .SetOptions (dict "params" (dict "param1" "value1")) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
`SetOptions` takes a [params options] map. The instance options will be passed to any [runner] script in the same group, as JSON.
|
||||
|
||||
|
||||
#### Runner
|
||||
|
||||
The `Runner` method takes an `ID` (`string`) as argument. No slashes. It returns an [OptionsSetter] that can be used to set [script options] for this runner.
|
||||
|
||||
```go-html-template
|
||||
{{ with js.Batch "js/mybatch" }}
|
||||
{{ with .Group "mygroup" }}
|
||||
{{ with .Runner "myrunner" }}
|
||||
{{ .SetOptions (dict "resource" (resources.Get "myrunner.js")) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
`SetOptions` takes a [script options] map.
|
||||
|
||||
The runner will receive a data structure with all instances for that group with a live binding of the [JavaScript import] of the defined `export`.
|
||||
|
||||
The runner script's export must be a function that takes one argument, the group data structure. An example of a group data structure as JSON is:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "leaflet",
|
||||
"scripts": [
|
||||
{
|
||||
"id": "mapjsx",
|
||||
"binding": JAVASCRIPT_BINDING,
|
||||
"instances": [
|
||||
{
|
||||
"id": "0",
|
||||
"params": {
|
||||
"c": "h-64",
|
||||
"lat": 48.8533173846729,
|
||||
"lon": 2.3497416090232535,
|
||||
"r": "map.jsx",
|
||||
"title": "Cathédrale Notre-Dame de Paris",
|
||||
"zoom": 23
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "1",
|
||||
"params": {
|
||||
"c": "h-64",
|
||||
"lat": 59.96300872062237,
|
||||
"lon": 10.663529183196863,
|
||||
"r": "map.jsx",
|
||||
"title": "Holmenkollen",
|
||||
"zoom": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Below is an example of a runner script that uses React to render elements. Note that the export (`default`) must match the `export` option in the [script options] (`default` is the default value for runner scripts) (runnable versions of examples on this page can be found at [js.Batch Demo Repo]):
|
||||
|
||||
|
||||
```js
|
||||
import * as ReactDOM from 'react-dom/client';
|
||||
import * as React from 'react';
|
||||
|
||||
export default function Run(group) {
|
||||
console.log('Running react-create-elements.js', group);
|
||||
const scripts = group.scripts;
|
||||
for (const script of scripts) {
|
||||
for (const instance of script.instances) {
|
||||
/* This is a convention in this project. */
|
||||
let elId = `${script.id}-${instance.id}`;
|
||||
let el = document.getElementById(elId);
|
||||
if (!el) {
|
||||
console.warn(`Element with id ${elId} not found`);
|
||||
continue;
|
||||
}
|
||||
const root = ReactDOM.createRoot(el);
|
||||
const reactEl = React.createElement(script.binding, instance.params);
|
||||
root.render(reactEl);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Config
|
||||
|
||||
Returns an [OptionsSetter] that can be used to set [build options] for the batch.
|
||||
|
||||
These are mostly the same as for [js.Build], but note that:
|
||||
|
||||
* `targetPath` is set automatically (there may be multiple outputs).
|
||||
* `format` must be `esm`, currently the only format supporting [code splitting].
|
||||
* `params` will be available in the `@params/config` namespace in the scripts. This way you can import both the [script] or [runner] params and the [config] params with:
|
||||
|
||||
```js
|
||||
import * as params from "@params";
|
||||
import * as config from "@params/config";
|
||||
```
|
||||
|
||||
Setting the `Config` for a batch can be done from any template (including shortcode templates), but will only be set once (the first will win):
|
||||
|
||||
```go-html-template
|
||||
{{ with js.Batch "js/mybatch" }}
|
||||
{{ with .Config }}
|
||||
{{ .SetOptions (dict
|
||||
"target" "es2023"
|
||||
"format" "esm"
|
||||
"jsx" "automatic"
|
||||
"loaders" (dict ".png" "dataurl")
|
||||
"minify" true
|
||||
"params" (dict "param1" "value1")
|
||||
)
|
||||
}}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### Build Options
|
||||
|
||||
format
|
||||
: (`string`) Currently only `esm` is supported in [ESBuild's code splitting].
|
||||
|
||||
{{% include "./_common/options.md" %}}
|
||||
|
||||
### Script Options
|
||||
|
||||
resource
|
||||
: The resource to build. This can be a file resource or a virtual resource.
|
||||
|
||||
export
|
||||
: The export to bind the runner to. Set it to `*` to export the [entire namespace](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#namespace_import). Default is `default` for [runner] scripts and `*` for other [scripts](#script).
|
||||
|
||||
importContext
|
||||
: An additional context for resolving imports. Hugo will always check this one first before falling back to `assets` and `node_modules`. A common use of this is to resolve imports inside a page bundle. See [import context](#import-context).
|
||||
|
||||
params
|
||||
: A map of parameters that will be passed to the script as JSON. These gets bound to the `@params` namespace:
|
||||
```js
|
||||
import * as params from '@params';
|
||||
```
|
||||
|
||||
### Script Options
|
||||
|
||||
### Params Options
|
||||
|
||||
params
|
||||
: A map of parameters that will be passed to the script as JSON.
|
||||
|
||||
### Import Context
|
||||
|
||||
Hugo will, by default, first try to resolve any import in [assets](/hugo-pipes/introduction/#asset-directory) and, if not found, let [ESBuild] resolve it (e.g. from `node_modules`). The `importContext` option can be used to set the first context for resolving imports. A common use of this is to resolve imports inside a [page bundle](/content-management/page-bundles/).
|
||||
|
||||
```go-html-template
|
||||
{{ $common := resources.Match "/js/headlessui/*.*" }}
|
||||
{{ $importContext := (slice $.Page ($common.Mount "/js/headlessui" ".")) }}
|
||||
```
|
||||
|
||||
You can pass any object that implements [Resource.Get](/methods/page/resources/#get). Pass a slice to set multiple contexts.
|
||||
|
||||
The example above uses [`Resources.Mount`] to resolve a folder inside `assets` relative to the page bundle.
|
||||
|
||||
### OptionsSetter
|
||||
|
||||
An `OptionsSetter` is a special object that is returned once only. This means that you should wrap it with [with]:
|
||||
|
||||
```go-html-template
|
||||
{{ with .Script "myscript" }}
|
||||
{{ .SetOptions (dict "resource" (resources.Get "myscript.js"))}}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
The `Build` method returns an object with the following structure:
|
||||
|
||||
* Groups (map)
|
||||
* [`Resources`]
|
||||
|
||||
Eeach [`Resource`] will be of media type `application/javascript` or `text/css`.
|
||||
|
||||
In a template you would typically handle one group with a given `ID` (e.g. scripts for the current section). Because of the concurrent build, this needs to be done in a [`templates.Defer`] block:
|
||||
|
||||
{{% note %}}
|
||||
The [`templates.Defer`] acts as a synchronisation point to handle scripts added concurrently by different templates. If you have a setup with where the batch is created in one go (in one template), you don't need it.
|
||||
|
||||
See [this discussion](https://discourse.gohugo.io/t/js-batch-with-simple-global-script/53002/5?u=bep) for more.
|
||||
|
||||
[`templates.Defer`]: /functions/templates/defer/
|
||||
{{% /note %}}
|
||||
|
||||
```go-html-template
|
||||
{{ $group := .group }}
|
||||
{{ with (templates.Defer (dict "key" $group "data" $group )) }}
|
||||
{{ with (js.Batch "js/mybatch") }}
|
||||
{{ with .Build }}
|
||||
{{ with index .Groups $ }}
|
||||
{{ range . }}
|
||||
{{ $s := . }}
|
||||
{{ if eq $s.MediaType.SubType "css" }}
|
||||
<link href="{{ $s.RelPermalink }}" rel="stylesheet" />
|
||||
{{ else }}
|
||||
<script src="{{ $s.RelPermalink }}" type="module"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
|
||||
## Known Issues
|
||||
|
||||
In the official documentation for [ESBuild's code splitting], there's a warning note in the header. The two issues are:
|
||||
|
||||
* `esm` is currently the only implemented output format. This means that it will not work for very old browsers. See [caniuse](https://caniuse.com/?search=ESM).
|
||||
* There's a known import ordering issue.
|
||||
|
||||
We have not seen the ordering issue as a problem during our [extensive testing](https://github.com/bep/hugojsbatchdemo) of this new feature with different libraries. There are two main cases:
|
||||
|
||||
1. Undefined execution order of imports, see [this comment](https://github.com/evanw/esbuild/issues/399#issuecomment-1458680887)
|
||||
2. Only one execution order of imports, see [this comment](https://github.com/evanw/esbuild/issues/399#issuecomment-735355932)
|
||||
|
||||
Many would say that both of the above are [code smells](https://en.wikipedia.org/wiki/Code_smell). The first one has a simple workaround in Hugo. Define the import order in its own script and make sure it gets passed early to ESBuild, e.g. by putting it in a script group with a name that comes early in the alphabet.
|
||||
|
||||
```js
|
||||
import './lib2.js';
|
||||
import './lib1.js';
|
||||
|
||||
console.log('entrypoints-workaround.js');
|
||||
|
||||
```
|
||||
|
||||
[build options]: #build-options
|
||||
[`Resource`]: https://gohugo.io/methods/resource/
|
||||
[`Resources`]: /methods/page/resources/
|
||||
[`Resources.Mount`]: /methods/page/resources/#mount
|
||||
[`templates.Defer`]: /functions/templates/defer/
|
||||
[code splitting]: https://esbuild.github.io/api/#splitting
|
||||
[config]: #config
|
||||
[ESBuild's code splitting]: https://esbuild.github.io/api/#splitting
|
||||
[ESBuild]: https://github.com/evanw/esbuild
|
||||
[group]: #group
|
||||
[instance]: #instance
|
||||
[JavaScript import]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
|
||||
[js.Batch Demo Repo]: https://github.com/bep/hugojsbatchdemo/
|
||||
[js.Build]: https://gohugo.io/hugo-pipes/js/#options
|
||||
[map]: https://gohugo.io/functions/collections/dictionary/
|
||||
[OptionsSetter]: #optionssetter
|
||||
[page bundles]: https://gohugo.io/content-management/page-bundles/
|
||||
[params options]: #params-options
|
||||
[runner]: #runner
|
||||
[script options]: #script-options
|
||||
[script]: #script
|
||||
[SetOptions]: #optionssetter
|
||||
[with]: https://gohugo.io/functions/go-template/with/
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
title: js.Build
|
||||
description: Bundles, transpiles, tree shakes, and minifies JavaScript resources.
|
||||
weight: 30
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
|
@ -45,94 +46,10 @@ 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.
|
||||
|
||||
params
|
||||
: (`map` or `slice`) Params that can be imported as JSON in your JS files, e.g.
|
||||
|
||||
```go-html-template
|
||||
{{ $js := resources.Get "js/main.js" | js.Build (dict "params" (dict "api" "https://example.org/api")) }}
|
||||
```
|
||||
And then in your JS file:
|
||||
|
||||
```js
|
||||
import * as params from '@params';
|
||||
```
|
||||
|
||||
Note that this is meant for small data sets, e.g. configuration settings. For larger data, please put/mount the files into `/assets` and import them directly.
|
||||
|
||||
minify
|
||||
: (`bool`)Let `js.Build` handle the minification.
|
||||
|
||||
inject
|
||||
: (`slice`) This option allows you to automatically replace a global variable with an import from another file. The path names must be relative to `assets`. See https://esbuild.github.io/api/#inject
|
||||
|
||||
shims
|
||||
: (`map`) This option allows swapping out a component with another. A common use case is to load dependencies like React from a CDN (with _shims_) when in production, but running with the full bundled `node_modules` dependency during development:
|
||||
|
||||
```go-html-template
|
||||
{{ $shims := dict "react" "js/shims/react.js" "react-dom" "js/shims/react-dom.js" }}
|
||||
{{ $js = $js | js.Build dict "shims" $shims }}
|
||||
```
|
||||
|
||||
The _shim_ files may look like these:
|
||||
|
||||
```js
|
||||
// js/shims/react.js
|
||||
module.exports = window.React;
|
||||
```
|
||||
|
||||
```js
|
||||
// js/shims/react-dom.js
|
||||
module.exports = window.ReactDOM;
|
||||
```
|
||||
|
||||
With the above, these imports should work in both scenarios:
|
||||
|
||||
```js
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom/client';
|
||||
```
|
||||
|
||||
target
|
||||
: (`string`) The language target. One of: `es5`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020` or `esnext`. Default is `esnext`.
|
||||
|
||||
externals
|
||||
: (`slice`) External dependencies. Use this to trim dependencies you know will never be executed. See https://esbuild.github.io/api/#external
|
||||
|
||||
defines
|
||||
: (`map`) Allow to define a set of string replacement to be performed when building. Should be a map where each key is to be replaced by its value.
|
||||
|
||||
```go-html-template
|
||||
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
|
||||
```
|
||||
|
||||
format
|
||||
: (`string`) The output format. One of: `iife`, `cjs`, `esm`. Default is `iife`, a self-executing function, suitable for inclusion as a `<script>` tag.
|
||||
|
||||
sourceMap
|
||||
: (`string`) Whether to generate `inline` or `external` source maps from esbuild. External source maps will be written to the target with the output file name + ".map". Input source maps can be read from js.Build and node modules and combined into the output source maps. By default, source maps are not created.
|
||||
|
||||
JSX {{< new-in 0.124.0 >}}
|
||||
: (`string`) How to handle/transform JSX syntax. One of: `transform`, `preserve`, `automatic`. Default is `transform`. Notably, the `automatic` transform was introduced in React 17+ and will cause the necessary JSX helper functions to be imported automatically. See https://esbuild.github.io/api/#jsx
|
||||
|
||||
JSXImportSource {{< new-in 0.124.0 >}}
|
||||
: (`string`) Which library to use to automatically import its JSX helper functions from. This only works if `JSX` is set to `automatic`. The specified library needs to be installed through npm and expose certain exports. See https://esbuild.github.io/api/#jsx-import-source
|
||||
|
||||
The combination of `JSX` and `JSXImportSource` is helpful if you want to use a non-React JSX library like Preact, e.g.:
|
||||
|
||||
```go-html-template
|
||||
{{ $js := resources.Get "js/main.jsx" | js.Build (dict "JSX" "automatic" "JSXImportSource" "preact") }}
|
||||
```
|
||||
|
||||
With the above, you can use Preact components and JSX without having to manually import `h` and `Fragment` every time:
|
||||
|
||||
```jsx
|
||||
import { render } from 'preact';
|
||||
|
||||
const App = () => <>Hello world!</>;
|
||||
|
||||
const container = document.getElementById('app');
|
||||
if (container) render(<App />, container);
|
||||
```
|
||||
{{% include "./_common/options.md" %}}
|
||||
|
||||
### Import JS code from /assets
|
||||
|
||||
|
|
13
docs/content/en/functions/js/_common/_index.md
Normal file
13
docs/content/en/functions/js/_common/_index.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
cascade:
|
||||
_build:
|
||||
list: never
|
||||
publishResources: false
|
||||
render: never
|
||||
---
|
||||
|
||||
<!--
|
||||
Files within this headless branch bundle are Markdown snippets. Each file must contain front matter delimiters, though front matter fields are not required.
|
||||
|
||||
Include the rendered content using the "include" shortcode.
|
||||
-->
|
99
docs/content/en/functions/js/_common/options.md
Normal file
99
docs/content/en/functions/js/_common/options.md
Normal file
|
@ -0,0 +1,99 @@
|
|||
---
|
||||
_comment: Do not remove front matter.
|
||||
---
|
||||
|
||||
params
|
||||
: (`map` or `slice`) Params that can be imported as JSON in your JS files, e.g.
|
||||
|
||||
```go-html-template
|
||||
{{ $js := resources.Get "js/main.js" | js.Build (dict "params" (dict "api" "https://example.org/api")) }}
|
||||
```
|
||||
And then in your JS file:
|
||||
|
||||
```js
|
||||
import * as params from '@params';
|
||||
```
|
||||
|
||||
Note that this is meant for small data sets, e.g. configuration settings. For larger data, please put/mount the files into `/assets` and import them directly.
|
||||
|
||||
minify
|
||||
: (`bool`)Let `js.Build` handle the minification.
|
||||
|
||||
loaders
|
||||
: (`map`) {{< new-in "0.140.0" >}} Configuring a loader for a given file type lets you load that file type with an import statement or a require call. For example configuring the .png file extension to use the data URL loader means importing a .png file gives you a data URLcontaining the contents of that image. Loaders available are `none`, `base64`, `binary`, `copy`, `css`, `dataurl`, `default`, `empty`, `file`, `global-css`, `js`, `json`, `jsx`, `local-css`, `text`, `ts`, `tsx`. See https://esbuild.github.io/api/#loader
|
||||
|
||||
inject
|
||||
: (`slice`) This option allows you to automatically replace a global variable with an import from another file. The path names must be relative to `assets`. See https://esbuild.github.io/api/#inject
|
||||
|
||||
shims
|
||||
: (`map`) This option allows swapping out a component with another. A common use case is to load dependencies like React from a CDN (with _shims_) when in production, but running with the full bundled `node_modules` dependency during development:
|
||||
|
||||
```go-html-template
|
||||
{{ $shims := dict "react" "js/shims/react.js" "react-dom" "js/shims/react-dom.js" }}
|
||||
{{ $js = $js | js.Build dict "shims" $shims }}
|
||||
```
|
||||
|
||||
The _shim_ files may look like these:
|
||||
|
||||
```js
|
||||
// js/shims/react.js
|
||||
module.exports = window.React;
|
||||
```
|
||||
|
||||
```js
|
||||
// js/shims/react-dom.js
|
||||
module.exports = window.ReactDOM;
|
||||
```
|
||||
|
||||
With the above, these imports should work in both scenarios:
|
||||
|
||||
```js
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom/client';
|
||||
```
|
||||
|
||||
target
|
||||
: (`string`) The language target. One of: `es5`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020` or `esnext`. Default is `esnext`.
|
||||
|
||||
platform {{< new-in 0.140.0 >}}
|
||||
: (`string`) One of `browser`, `node`, `neutral`. Default is `browser`. See https://esbuild.github.io/api/#platform
|
||||
|
||||
externals
|
||||
: (`slice`) External dependencies. Use this to trim dependencies you know will never be executed. See https://esbuild.github.io/api/#external
|
||||
|
||||
defines
|
||||
: (`map`) Allow to define a set of string replacement to be performed when building. Should be a map where each key is to be replaced by its value.
|
||||
|
||||
```go-html-template
|
||||
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
|
||||
```
|
||||
|
||||
sourceMap
|
||||
: (`string`) Whether to generate `inline`, `linked` or `external` source maps from esbuild. Linked and external source maps will be written to the target with the output file name + ".map". When `linked` a `sourceMappingURL` will also be written to the output file. By default, source maps are not created. Note that the `linked` option was added in Hugo 0.140.0.
|
||||
|
||||
sourcesContent {{< new-in 0.140.0 >}}
|
||||
: (`bool`) Whether to include the content of the source files in the source map. By default, this is `true`.
|
||||
|
||||
|
||||
JSX {{< new-in 0.124.0 >}}
|
||||
: (`string`) How to handle/transform JSX syntax. One of: `transform`, `preserve`, `automatic`. Default is `transform`. Notably, the `automatic` transform was introduced in React 17+ and will cause the necessary JSX helper functions to be imported automatically. See https://esbuild.github.io/api/#jsx
|
||||
|
||||
JSXImportSource {{< new-in 0.124.0 >}}
|
||||
: (`string`) Which library to use to automatically import its JSX helper functions from. This only works if `JSX` is set to `automatic`. The specified library needs to be installed through npm and expose certain exports. See https://esbuild.github.io/api/#jsx-import-source
|
||||
|
||||
The combination of `JSX` and `JSXImportSource` is helpful if you want to use a non-React JSX library like Preact, e.g.:
|
||||
|
||||
```go-html-template
|
||||
{{ $js := resources.Get "js/main.jsx" | js.Build (dict "JSX" "automatic" "JSXImportSource" "preact") }}
|
||||
```
|
||||
|
||||
With the above, you can use Preact components and JSX without having to manually import `h` and `Fragment` every time:
|
||||
|
||||
```jsx
|
||||
import { render } from 'preact';
|
||||
|
||||
const App = () => <>Hello world!</>;
|
||||
|
||||
const container = document.getElementById('app');
|
||||
if (container) render(<App />, container);
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue