shithub: hugo

Download patch

ref: eded9ac2a05b9a7244c25c70ca8f761b69b33385
parent: 8d72512825b4cee12dc1952004f48fd076a3517b
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Tue Jul 21 13:03:06 EDT 2020

resources/js: Simplify options handling

Mostly to minify cache hash breakage.

Updates #7499

--- a/resources/resource_transformers/js/build.go
+++ b/resources/resource_transformers/js/build.go
@@ -62,34 +62,20 @@
 	JSXFragment string
 }
 
-type internalOptions struct {
-	TargetPath  string
-	Minify      bool
-	Target      string
-	JSXFactory  string
-	JSXFragment string
-
-	Externals []string `hash:"set"`
-
-	Defines map[string]string
-
-	// These are currently not exposed in the public Options struct,
-	// but added here to make the options hash as stable as possible for
-	// whenever we do.
-	TSConfig string
-}
-
-func DecodeOptions(m map[string]interface{}) (opts Options, err error) {
-	if m == nil {
+func decodeOptions(m map[string]interface{}) (opts Options, err error) {
+	err = mapstructure.WeakDecode(m, &opts)
+	if err != nil {
 		return
 	}
-	err = mapstructure.WeakDecode(m, &opts)
-	err = mapstructure.WeakDecode(m, &opts)
 
 	if opts.TargetPath != "" {
 		opts.TargetPath = helpers.ToSlashTrimLeading(opts.TargetPath)
 	}
 
+	if opts.Target == "" {
+		opts.Target = defaultTarget
+	}
+
 	opts.Target = strings.ToLower(opts.Target)
 
 	return
@@ -105,26 +91,31 @@
 }
 
 type buildTransformation struct {
-	options internalOptions
-	rs      *resources.Spec
-	sfs     *filesystems.SourceFilesystem
+	optsm map[string]interface{}
+	rs    *resources.Spec
+	sfs   *filesystems.SourceFilesystem
 }
 
 func (t *buildTransformation) Key() internal.ResourceTransformationKey {
-	return internal.NewResourceTransformationKey("jsbuild", t.options)
+	return internal.NewResourceTransformationKey("jsbuild", t.optsm)
 }
 
 func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx) error {
 	ctx.OutMediaType = media.JavascriptType
 
-	if t.options.TargetPath != "" {
-		ctx.OutPath = t.options.TargetPath
+	opts, err := decodeOptions(t.optsm)
+	if err != nil {
+		return err
+	}
+
+	if opts.TargetPath != "" {
+		ctx.OutPath = opts.TargetPath
 	} else {
 		ctx.ReplaceOutPathExtension(".js")
 	}
 
 	var target api.Target
-	switch t.options.Target {
+	switch opts.Target {
 	case defaultTarget:
 		target = api.ESNext
 	case "es5":
@@ -142,7 +133,7 @@
 	case "es2020":
 		target = api.ES2020
 	default:
-		return fmt.Errorf("invalid target: %q", t.options.Target)
+		return fmt.Errorf("invalid target: %q", opts.Target)
 	}
 
 	var loader api.Loader
@@ -176,18 +167,18 @@
 
 		Target: target,
 
-		MinifyWhitespace:  t.options.Minify,
-		MinifyIdentifiers: t.options.Minify,
-		MinifySyntax:      t.options.Minify,
+		MinifyWhitespace:  opts.Minify,
+		MinifyIdentifiers: opts.Minify,
+		MinifySyntax:      opts.Minify,
 
-		Defines: t.options.Defines,
+		Defines: cast.ToStringMapString(opts.Defines),
 
-		Externals: t.options.Externals,
+		Externals: opts.Externals,
 
-		JSXFactory:  t.options.JSXFactory,
-		JSXFragment: t.options.JSXFragment,
+		JSXFactory:  opts.JSXFactory,
+		JSXFragment: opts.JSXFragment,
 
-		Tsconfig: t.options.TSConfig,
+		//Tsconfig: opts.TSConfig,
 
 		Stdin: &api.StdinOptions{
 			Contents:   string(src),
@@ -208,28 +199,8 @@
 	return nil
 }
 
-func (c *Client) Process(res resources.ResourceTransformer, opts Options) (resource.Resource, error) {
+func (c *Client) Process(res resources.ResourceTransformer, opts map[string]interface{}) (resource.Resource, error) {
 	return res.Transform(
-		&buildTransformation{rs: c.rs, sfs: c.sfs, options: toInternalOptions(opts)},
+		&buildTransformation{rs: c.rs, sfs: c.sfs, optsm: opts},
 	)
-}
-
-func toInternalOptions(opts Options) internalOptions {
-	target := opts.Target
-	if target == "" {
-		target = defaultTarget
-	}
-	var defines map[string]string
-	if opts.Defines != nil {
-		defines = cast.ToStringMapString(opts.Defines)
-	}
-	return internalOptions{
-		TargetPath:  opts.TargetPath,
-		Minify:      opts.Minify,
-		Target:      target,
-		Externals:   opts.Externals,
-		Defines:     defines,
-		JSXFactory:  opts.JSXFactory,
-		JSXFragment: opts.JSXFragment,
-	}
 }
--- a/resources/resource_transformers/js/build_test.go
+++ b/resources/resource_transformers/js/build_test.go
@@ -24,47 +24,11 @@
 func TestOptionKey(t *testing.T) {
 	c := qt.New(t)
 
-	opts := internalOptions{
-		TargetPath: "foo",
+	opts := map[string]interface{}{
+		"TargetPath": "foo",
 	}
 
-	key := (&buildTransformation{options: opts}).Key()
+	key := (&buildTransformation{optsm: opts}).Key()
 
-	c.Assert(key.Value(), qt.Equals, "jsbuild_9405671309963492201")
-}
-
-func TestToInternalOptions(t *testing.T) {
-	c := qt.New(t)
-
-	o := Options{
-		TargetPath:  "v1",
-		Target:      "v2",
-		JSXFactory:  "v3",
-		JSXFragment: "v4",
-		Externals:   []string{"react"},
-		Defines:     map[string]interface{}{"process.env.NODE_ENV": "production"},
-		Minify:      true,
-	}
-
-	c.Assert(toInternalOptions(o), qt.DeepEquals, internalOptions{
-		TargetPath:  "v1",
-		Minify:      true,
-		Target:      "v2",
-		JSXFactory:  "v3",
-		JSXFragment: "v4",
-		Externals:   []string{"react"},
-		Defines:     map[string]string{"process.env.NODE_ENV": "production"},
-		TSConfig:    "",
-	})
-
-	c.Assert(toInternalOptions(Options{}), qt.DeepEquals, internalOptions{
-		TargetPath:  "",
-		Minify:      false,
-		Target:      "esnext",
-		JSXFactory:  "",
-		JSXFragment: "",
-		Externals:   nil,
-		Defines:     nil,
-		TSConfig:    "",
-	})
+	c.Assert(key.Value(), qt.Equals, "jsbuild_15565843046704064284")
 }
--- a/tpl/js/js.go
+++ b/tpl/js/js.go
@@ -16,7 +16,6 @@
 
 import (
 	"github.com/gohugoio/hugo/deps"
-	"github.com/gohugoio/hugo/helpers"
 	"github.com/gohugoio/hugo/resources"
 	"github.com/gohugoio/hugo/resources/resource"
 	"github.com/gohugoio/hugo/resources/resource_transformers/js"
@@ -58,16 +57,10 @@
 		}
 	}
 
-	var options js.Options
 	if targetPath != "" {
-		options.TargetPath = helpers.ToSlashTrimLeading(targetPath)
-	} else if m != nil {
-		options, err = js.DecodeOptions(m)
-		if err != nil {
-			return nil, err
-		}
+		m = map[string]interface{}{"targetPath": targetPath}
 	}
 
-	return ns.client.Process(r, options)
+	return ns.client.Process(r, m)
 
 }