aboutsummaryrefslogtreecommitdiffhomepage
path: root/tpl
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2024-12-10 16:22:08 +0100
committerBjørn Erik Pedersen <[email protected]>2024-12-12 21:43:17 +0100
commite293e7ca6dcc34cded7eb90a644b5c720c2179cf (patch)
treedee8e8d272660d23aa7b76576e8267fc70c34f78 /tpl
parent157d86414d43f6801e2a6996108f67d28679eac5 (diff)
downloadhugo-e293e7ca6dcc34cded7eb90a644b5c720c2179cf.tar.gz
hugo-e293e7ca6dcc34cded7eb90a644b5c720c2179cf.zip
Add js.Batch
Fixes #12626 Closes #7499 Closes #9978 Closes #12879 Closes #13113 Fixes #13116
Diffstat (limited to 'tpl')
-rw-r--r--tpl/debug/debug.go4
-rw-r--r--tpl/fmt/fmt.go3
-rw-r--r--tpl/js/init.go5
-rw-r--r--tpl/js/js.go57
-rw-r--r--tpl/partials/partials.go3
-rw-r--r--tpl/tplimpl/embedded/templates/_hugo/build/js/batch-esm-runner.gotmpl16
-rw-r--r--tpl/tplimpl/template.go8
-rw-r--r--tpl/tplimpl/template_funcs.go7
8 files changed, 83 insertions, 20 deletions
diff --git a/tpl/debug/debug.go b/tpl/debug/debug.go
index ae1acf5eb..fd676f0e2 100644
--- a/tpl/debug/debug.go
+++ b/tpl/debug/debug.go
@@ -41,7 +41,7 @@ func New(d *deps.Deps) *Namespace {
l := d.Log.InfoCommand("timer")
- d.BuildEndListeners.Add(func() {
+ d.BuildEndListeners.Add(func(...any) bool {
type data struct {
Name string
Count int
@@ -84,6 +84,8 @@ func New(d *deps.Deps) *Namespace {
}
ns.timers = make(map[string][]*timer)
+
+ return false
})
return ns
diff --git a/tpl/fmt/fmt.go b/tpl/fmt/fmt.go
index e9c18360a..264cb1435 100644
--- a/tpl/fmt/fmt.go
+++ b/tpl/fmt/fmt.go
@@ -30,8 +30,9 @@ func New(d *deps.Deps) *Namespace {
logger: d.Log,
}
- d.BuildStartListeners.Add(func() {
+ d.BuildStartListeners.Add(func(...any) bool {
ns.logger.Reset()
+ return false
})
return ns
diff --git a/tpl/js/init.go b/tpl/js/init.go
index 69d7c7275..97e76c33d 100644
--- a/tpl/js/init.go
+++ b/tpl/js/init.go
@@ -24,7 +24,10 @@ const name = "js"
func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
- ctx := New(d)
+ ctx, err := New(d)
+ if err != nil {
+ panic(err)
+ }
ns := &internal.TemplateFuncsNamespace{
Name: name,
diff --git a/tpl/js/js.go b/tpl/js/js.go
index c68e0af92..b686b76a7 100644
--- a/tpl/js/js.go
+++ b/tpl/js/js.go
@@ -1,4 +1,4 @@
-// Copyright 2020 The Hugo Authors. All rights reserved.
+// Copyright 2024 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,29 +17,47 @@ package js
import (
"errors"
+ "github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/deps"
+ "github.com/gohugoio/hugo/internal/js/esbuild"
"github.com/gohugoio/hugo/resources"
"github.com/gohugoio/hugo/resources/resource"
+ "github.com/gohugoio/hugo/resources/resource_factories/create"
"github.com/gohugoio/hugo/resources/resource_transformers/babel"
- "github.com/gohugoio/hugo/resources/resource_transformers/js"
+ jstransform "github.com/gohugoio/hugo/resources/resource_transformers/js"
"github.com/gohugoio/hugo/tpl/internal/resourcehelpers"
)
// New returns a new instance of the js-namespaced template functions.
-func New(deps *deps.Deps) *Namespace {
- if deps.ResourceSpec == nil {
- return &Namespace{}
+func New(d *deps.Deps) (*Namespace, error) {
+ if d.ResourceSpec == nil {
+ return &Namespace{}, nil
}
- return &Namespace{
- client: js.New(deps.BaseFs.Assets, deps.ResourceSpec),
- babelClient: babel.New(deps.ResourceSpec),
+
+ batcherClient, err := esbuild.NewBatcherClient(d)
+ if err != nil {
+ return nil, err
}
+
+ return &Namespace{
+ d: d,
+ jsTransformClient: jstransform.New(d.BaseFs.Assets, d.ResourceSpec),
+ jsBatcherClient: batcherClient,
+ jsBatcherStore: maps.NewCache[string, esbuild.Batcher](),
+ createClient: create.New(d.ResourceSpec),
+ babelClient: babel.New(d.ResourceSpec),
+ }, nil
}
// Namespace provides template functions for the "js" namespace.
type Namespace struct {
- client *js.Client
- babelClient *babel.Client
+ d *deps.Deps
+
+ jsTransformClient *jstransform.Client
+ createClient *create.Client
+ babelClient *babel.Client
+ jsBatcherClient *esbuild.BatcherClient
+ jsBatcherStore *maps.Cache[string, esbuild.Batcher]
}
// Build processes the given Resource with ESBuild.
@@ -65,7 +83,24 @@ func (ns *Namespace) Build(args ...any) (resource.Resource, error) {
m = map[string]any{"targetPath": targetPath}
}
- return ns.client.Process(r, m)
+ return ns.jsTransformClient.Process(r, m)
+}
+
+// Batch creates a new Batcher with the given ID.
+// Repeated calls with the same ID will return the same Batcher.
+// The ID will be used to name the root directory of the batch.
+// Forward slashes in the ID is allowed.
+func (ns *Namespace) Batch(id string) (esbuild.Batcher, error) {
+ if err := esbuild.ValidateBatchID(id, true); err != nil {
+ return nil, err
+ }
+ b, err := ns.jsBatcherStore.GetOrCreate(id, func() (esbuild.Batcher, error) {
+ return ns.jsBatcherClient.New(id)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return b, nil
}
// Babel processes the given Resource with Babel.
diff --git a/tpl/partials/partials.go b/tpl/partials/partials.go
index 8de312fd8..4441b5fa5 100644
--- a/tpl/partials/partials.go
+++ b/tpl/partials/partials.go
@@ -81,8 +81,9 @@ func New(deps *deps.Deps) *Namespace {
cache := &partialCache{cache: lru}
deps.BuildStartListeners.Add(
- func() {
+ func(...any) bool {
cache.clear()
+ return false
})
return &Namespace{
diff --git a/tpl/tplimpl/embedded/templates/_hugo/build/js/batch-esm-runner.gotmpl b/tpl/tplimpl/embedded/templates/_hugo/build/js/batch-esm-runner.gotmpl
new file mode 100644
index 000000000..e1b3b9bc3
--- /dev/null
+++ b/tpl/tplimpl/embedded/templates/_hugo/build/js/batch-esm-runner.gotmpl
@@ -0,0 +1,16 @@
+{{ range $i, $e := .Scripts -}}
+ {{ printf "import { %s as Script%d } from %q;" .Export $i .Import }}
+{{ end -}}
+{{ range $i, $e := .Runners }}
+ {{ printf "import { %s as Run%d } from %q;" .Export $i .Import }}
+{{ end }}
+{{/* */}}
+let scripts = [];
+{{ range $i, $e := .Scripts -}}
+ scripts.push({{ .RunnerJSON $i }});
+{{ end -}}
+{{/* */}}
+{{ range $i, $e := .Runners }}
+ {{ $id := printf "Run%d" $i }}
+ {{ $id }}(scripts);
+{{ end }}
diff --git a/tpl/tplimpl/template.go b/tpl/tplimpl/template.go
index fd07db68e..9e2af046d 100644
--- a/tpl/tplimpl/template.go
+++ b/tpl/tplimpl/template.go
@@ -695,13 +695,13 @@ func (t *templateHandler) applyBaseTemplate(overlay, base templateInfo) (tpl.Tem
if !base.IsZero() {
templ, err = templ.Parse(base.template)
if err != nil {
- return nil, base.errWithFileContext("parse failed", err)
+ return nil, base.errWithFileContext("text: base: parse failed", err)
}
}
templ, err = texttemplate.Must(templ.Clone()).Parse(overlay.template)
if err != nil {
- return nil, overlay.errWithFileContext("parse failed", err)
+ return nil, overlay.errWithFileContext("text: overlay: parse failed", err)
}
// The extra lookup is a workaround, see
@@ -720,13 +720,13 @@ func (t *templateHandler) applyBaseTemplate(overlay, base templateInfo) (tpl.Tem
if !base.IsZero() {
templ, err = templ.Parse(base.template)
if err != nil {
- return nil, base.errWithFileContext("parse failed", err)
+ return nil, base.errWithFileContext("html: base: parse failed", err)
}
}
templ, err = htmltemplate.Must(templ.Clone()).Parse(overlay.template)
if err != nil {
- return nil, overlay.errWithFileContext("parse failed", err)
+ return nil, overlay.errWithFileContext("html: overlay: parse failed", err)
}
// The extra lookup is a workaround, see
diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go
index 3daba74a0..d73d4d336 100644
--- a/tpl/tplimpl/template_funcs.go
+++ b/tpl/tplimpl/template_funcs.go
@@ -251,6 +251,9 @@ func newTemplateExecuter(d *deps.Deps) (texttemplate.Executer, map[string]reflec
}
func createFuncMap(d *deps.Deps) map[string]any {
+ if d.TmplFuncMap != nil {
+ return d.TmplFuncMap
+ }
funcMap := template.FuncMap{}
nsMap := make(map[string]any)
@@ -292,5 +295,7 @@ func createFuncMap(d *deps.Deps) map[string]any {
}
}
- return funcMap
+ d.TmplFuncMap = funcMap
+
+ return d.TmplFuncMap
}