diff options
author | Andreas Richter <richtera@users.noreply.github.com> | 2021-01-18 12:38:09 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-18 12:38:09 +0300 |
commit | 2c8b5d9165011c4b24b494e661ae60dfc7bb7d1b (patch) | |
tree | 1fccfe098c0ad5a85a030ba918914ea4191c658c /resources | |
parent | 0004a733c85cee991a8a170e93cd69c326cc8f2f (diff) |
pipes: Add external source map support to js.Build and Babel
Fixes #8132
Diffstat (limited to 'resources')
-rw-r--r-- | resources/resource_transformers/babel/babel.go | 51 | ||||
-rw-r--r-- | resources/resource_transformers/js/build.go | 30 | ||||
-rw-r--r-- | resources/resource_transformers/js/options.go | 2 | ||||
-rw-r--r-- | resources/resource_transformers/js/options_test.go | 18 |
4 files changed, 99 insertions, 2 deletions
diff --git a/resources/resource_transformers/babel/babel.go b/resources/resource_transformers/babel/babel.go index 204153705..e291b210b 100644 --- a/resources/resource_transformers/babel/babel.go +++ b/resources/resource_transformers/babel/babel.go @@ -16,7 +16,11 @@ package babel import ( "bytes" "io" + "io/ioutil" + "os" + "path" "path/filepath" + "regexp" "strconv" "github.com/cli/safeexec" @@ -43,8 +47,10 @@ type Options struct { Compact *bool Verbose bool NoBabelrc bool + SourceMap string } +// DecodeOptions decodes options to and generates command flags func DecodeOptions(m map[string]interface{}) (opts Options, err error) { if m == nil { return @@ -56,6 +62,14 @@ func DecodeOptions(m map[string]interface{}) (opts Options, err error) { func (opts Options) toArgs() []string { var args []string + // external is not a known constant on the babel command line + // .sourceMaps must be a boolean, "inline", "both", or undefined + switch opts.SourceMap { + case "external": + args = append(args, "--source-maps") + case "inline": + args = append(args, "--source-maps=inline") + } if opts.Minified { args = append(args, "--minified") } @@ -141,6 +155,8 @@ func (t *babelTransformation) Transform(ctx *resources.ResourceTransformationCtx } } + ctx.ReplaceOutPathExtension(".js") + var cmdArgs []string if configFile != "" { @@ -153,13 +169,24 @@ func (t *babelTransformation) Transform(ctx *resources.ResourceTransformationCtx } cmdArgs = append(cmdArgs, "--filename="+ctx.SourcePath) + // Create compile into a real temp file: + // 1. separate stdout/stderr messages from babel (https://github.com/gohugoio/hugo/issues/8136) + // 2. allow generation and retrieval of external source map. + compileOutput, err := ioutil.TempFile("", "compileOut-*.js") + if err != nil { + return err + } + + cmdArgs = append(cmdArgs, "--out-file="+compileOutput.Name()) + defer os.Remove(compileOutput.Name()) + cmd, err := hexec.SafeCommand(binary, cmdArgs...) if err != nil { return err } - cmd.Stdout = ctx.To cmd.Stderr = io.MultiWriter(infoW, &errBuf) + cmd.Stdout = cmd.Stderr cmd.Env = hugo.GetExecEnviron(t.rs.WorkingDir, t.rs.Cfg, t.rs.BaseFs.Assets.Fs) stdin, err := cmd.StdinPipe() @@ -177,6 +204,28 @@ func (t *babelTransformation) Transform(ctx *resources.ResourceTransformationCtx return errors.Wrap(err, errBuf.String()) } + content, err := ioutil.ReadAll(compileOutput) + if err != nil { + return err + } + + mapFile := compileOutput.Name() + ".map" + if _, err := os.Stat(mapFile); err == nil { + defer os.Remove(mapFile) + sourceMap, err := ioutil.ReadFile(mapFile) + if err != nil { + return err + } + if err = ctx.PublishSourceMap(string(sourceMap)); err != nil { + return err + } + targetPath := path.Base(ctx.OutPath) + ".map" + re := regexp.MustCompile(`//# sourceMappingURL=.*\n?`) + content = []byte(re.ReplaceAllString(string(content), "//# sourceMappingURL="+targetPath+"\n")) + } + + ctx.To.Write(content) + return nil } diff --git a/resources/resource_transformers/js/build.go b/resources/resource_transformers/js/build.go index 5ff21cf02..0d70bdc33 100644 --- a/resources/resource_transformers/js/build.go +++ b/resources/resource_transformers/js/build.go @@ -18,6 +18,8 @@ import ( "fmt" "io/ioutil" "os" + "path" + "regexp" "strings" "github.com/spf13/afero" @@ -92,6 +94,14 @@ func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx return err } + if buildOptions.Sourcemap == api.SourceMapExternal && buildOptions.Outdir == "" { + buildOptions.Outdir, err = ioutil.TempDir(os.TempDir(), "compileOutput") + if err != nil { + return err + } + defer os.Remove(buildOptions.Outdir) + } + result := api.Build(buildOptions) if len(result.Errors) > 0 { @@ -145,7 +155,25 @@ func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx return errors[0] } - ctx.To.Write(result.OutputFiles[0].Contents) + if buildOptions.Sourcemap == api.SourceMapExternal { + content := string(result.OutputFiles[1].Contents) + symPath := path.Base(ctx.OutPath) + ".map" + re := regexp.MustCompile(`//# sourceMappingURL=.*\n?`) + content = re.ReplaceAllString(content, "//# sourceMappingURL="+symPath+"\n") + + if err = ctx.PublishSourceMap(string(result.OutputFiles[0].Contents)); err != nil { + return err + } + _, err := ctx.To.Write([]byte(content)) + if err != nil { + return err + } + } else { + _, err := ctx.To.Write(result.OutputFiles[0].Contents) + if err != nil { + return err + } + } return nil } diff --git a/resources/resource_transformers/js/options.go b/resources/resource_transformers/js/options.go index 75daa0cad..5236fe126 100644 --- a/resources/resource_transformers/js/options.go +++ b/resources/resource_transformers/js/options.go @@ -338,6 +338,8 @@ func toBuildOptions(opts Options) (buildOptions api.BuildOptions, err error) { switch opts.SourceMap { case "inline": sourceMap = api.SourceMapInline + case "external": + sourceMap = api.SourceMapExternal case "": sourceMap = api.SourceMapNone default: diff --git a/resources/resource_transformers/js/options_test.go b/resources/resource_transformers/js/options_test.go index f07ccc26b..f425c3e75 100644 --- a/resources/resource_transformers/js/options_test.go +++ b/resources/resource_transformers/js/options_test.go @@ -109,4 +109,22 @@ func TestToBuildOptions(t *testing.T) { Loader: api.LoaderJS, }, }) + + opts, err = toBuildOptions(Options{ + Target: "es2018", Format: "cjs", Minify: true, mediaType: media.JavascriptType, + SourceMap: "external", + }) + c.Assert(err, qt.IsNil) + c.Assert(opts, qt.DeepEquals, api.BuildOptions{ + Bundle: true, + Target: api.ES2018, + Format: api.FormatCommonJS, + MinifyIdentifiers: true, + MinifySyntax: true, + MinifyWhitespace: true, + Sourcemap: api.SourceMapExternal, + Stdin: &api.StdinOptions{ + Loader: api.LoaderJS, + }, + }) } |