Skip to content

Commit

Permalink
resources/js: Simplify options handling
Browse files Browse the repository at this point in the history
Mostly to minify cache hash breakage.

Updates #7499
  • Loading branch information
bep committed Jul 22, 2020
1 parent 8d72512 commit eded9ac
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 108 deletions.
89 changes: 30 additions & 59 deletions resources/resource_transformers/js/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,34 +62,20 @@ type Options struct {
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
Expand All @@ -105,26 +91,31 @@ func New(fs *filesystems.SourceFilesystem, rs *resources.Spec) *Client {
}

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":
Expand All @@ -142,7 +133,7 @@ func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx
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
Expand Down Expand Up @@ -176,18 +167,18 @@ func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx

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),
Expand All @@ -208,28 +199,8 @@ func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx
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,
}
}
44 changes: 4 additions & 40 deletions resources/resource_transformers/js/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,11 @@ import (
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")
}
11 changes: 2 additions & 9 deletions tpl/js/js.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package js

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"
Expand Down Expand Up @@ -58,16 +57,10 @@ func (ns *Namespace) Build(args ...interface{}) (resource.Resource, error) {
}
}

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)

}

0 comments on commit eded9ac

Please sign in to comment.