Skip to content

Commit

Permalink
Merge pull request #338 from hlanderdev/master
Browse files Browse the repository at this point in the history
Bundling with esbuild
  • Loading branch information
jimafisk authored Aug 20, 2024
2 parents a9aeedd + fce65e0 commit 55b41f8
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 5 deletions.
13 changes: 12 additions & 1 deletion cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ var BenchmarkFlag bool
// MinifyFlag condenses the JavaScript output so it runs faster in the browser.
var MinifyFlag bool

// BundleFlag uses esbuild to bundle the single page application (SPA) into a single file, improving the first page load time.
var BundleFlag bool

// ConfigFileFlag allows you to point to a nonstandard sitewide configuration file for the build (instead of plenti.json).
var ConfigFileFlag string

Expand Down Expand Up @@ -65,6 +68,7 @@ func Build() error {
build.CheckVerboseFlag(VerboseFlag)
build.CheckBenchmarkFlag(BenchmarkFlag)
build.CheckMinifyFlag(MinifyFlag)
build.CheckBundleFlag(BundleFlag)

var err error
// Handle panic when someone tries building outside of a valid Plenti site.
Expand Down Expand Up @@ -183,6 +187,12 @@ func Build() error {
log.Fatal("\nError in Minify build step", err)
}

// Run Bundler
err = build.Bundle(spaPath)
if err != nil {
log.Fatal("\nError in Bundle build step", err)
}

Building = false

// only relates to defer recover
Expand All @@ -204,7 +214,8 @@ func init() {
// buildCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
buildCmd.Flags().StringVarP(&OutputDirFlag, "output", "o", "", "change name of the public build directory")
buildCmd.Flags().BoolVarP(&VerboseFlag, "verbose", "v", false, "show log messages")
buildCmd.Flags().BoolVarP(&BenchmarkFlag, "benchmark", "b", false, "display build time statistics")
buildCmd.Flags().BoolVarP(&BenchmarkFlag, "profile", "P", false, "display build time statistics")
buildCmd.Flags().BoolVarP(&MinifyFlag, "minify", "m", true, "minify JS output for faster performance")
buildCmd.Flags().BoolVarP(&BundleFlag, "bundle", "b", false, "bundle the JS output for faster initial load times")
buildCmd.Flags().StringVarP(&ConfigFileFlag, "config", "c", "plenti.json", "use a custom sitewide configuration file")
}
90 changes: 90 additions & 0 deletions cmd/build/bundle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package build

import (
"errors"
"fmt"
"os"
"path"
"time"

"github.com/evanw/esbuild/pkg/api"
)

var bundleFlag bool

func CheckBundleFlag(flag bool) {
bundleFlag = flag
}

func Bundle(spaPath string) error {

defer Benchmark(time.Now(), "Running Bundler")

Log("\nRunning esbuild to bundle the JS output")

if bundleFlag {

mainJsFilePath := path.Join(spaPath, "core/main.js")

if err := mkCustomCmsFieldsDir(spaPath); err != nil {
return err
}

tmpDir, err := os.MkdirTemp("", "*")
if err != nil {
return fmt.Errorf("\nCould not create temporary directory for bundle output: %w\n", err)
}
defer os.RemoveAll(tmpDir)

tmpOutputFilePath := path.Join(tmpDir, "out.js")

result := api.Build(api.BuildOptions{
EntryPoints: []string{mainJsFilePath},
Bundle: true,
Outfile: tmpOutputFilePath,
Write: true,
})
if len(result.Errors) != 0 {
errs := make([]error, 0, len(result.Errors))
for _, msg := range result.Errors {
errs = append(errs, errors.New(msg.Text))
}
return fmt.Errorf("\nCould not bundle js output:\n%w\n", errors.Join(errs...))
}

styleFilePath := path.Join(spaPath, "bundle.css")
tmpSytleFilePath := path.Join(tmpDir, "bundle.css")
if err := copyFile(styleFilePath, tmpSytleFilePath); err != nil {
return fmt.Errorf("\nCould not copy bundle.css to temp file in bundle process: %w\n", err)
}

if err := os.RemoveAll(spaPath); err != nil {
return fmt.Errorf("\nCould clear spa directory in bundle process: %w\n", err)
}

if err := os.MkdirAll(path.Join(spaPath, "core"), 0755); err != nil {
return fmt.Errorf("\nCould recreate spa directory in bundle process: %w\n", err)
}

if err := copyFile(tmpSytleFilePath, styleFilePath); err != nil {
return fmt.Errorf("\nCould not copy bundle.css to temp file in bundle process: %w\n", err)
}

if err := copyFile(tmpOutputFilePath, mainJsFilePath); err != nil {
return fmt.Errorf("\nCould not copy temp file to main.js in bundle process: %w\n", err)
}
}
return nil
}

// mkCustomCmsFieldsDir ensures 'layouts/_fields/' exists to avoid an esbuild error
// related to a dynamic import in core/cms/dynamic_form_input[.js|.svelte]
func mkCustomCmsFieldsDir(spaPath string) error {
path := path.Join(spaPath, "layouts/_fields/")
err := os.MkdirAll(path, os.ModePerm)
if err != nil {
return fmt.Errorf("\nCould not create custom cms field directory '%s': %w\n", path, err)
}
return nil
}

3 changes: 2 additions & 1 deletion cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,9 @@ func init() {
serveCmd.Flags().StringVarP(&OutputDirFlag, "output", "o", "", "change name of the public build directory")
serveCmd.Flags().BoolVarP(&BuildFlag, "build", "B", true, "set \"false\" to disable build step")
serveCmd.Flags().BoolVarP(&VerboseFlag, "verbose", "v", false, "show log messages")
serveCmd.Flags().BoolVarP(&BenchmarkFlag, "benchmark", "b", false, "display build time statistics")
serveCmd.Flags().BoolVarP(&BenchmarkFlag, "profile", "P", false, "display build time statistics")
serveCmd.Flags().BoolVarP(&MinifyFlag, "minify", "m", true, "minify JS output for faster performance")
serveCmd.Flags().BoolVarP(&BundleFlag, "bundle", "b", false, "bundle the JS output for faster initial load times")
serveCmd.Flags().BoolVarP(&SSLFlag, "ssl", "s", false, "ssl/tls encryption to serve localhost over https")
serveCmd.Flags().BoolVarP(&build.Doreload, "live-reload", "L", false, "Enable live reload")
serveCmd.Flags().BoolVarP(&LocalFlag, "local", "l", true, "set false to emulate remote server")
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ toolchain go1.21.1
require (
github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/briandowns/spinner v1.12.0
github.com/evanw/esbuild v0.23.1
github.com/fsnotify/fsnotify v1.7.0
github.com/gerald1248/httpscerts v0.0.0-20170315065746-2c461ceb29ee
github.com/go-git/go-git/v5 v5.11.0
Expand All @@ -28,7 +29,6 @@ require (
github.com/cloudflare/circl v1.3.7 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanw/esbuild v0.21.0 // indirect
github.com/fatih/color v1.10.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcej
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/evanw/esbuild v0.21.0 h1:r1MUzkT+lu3UZeTwlxscikUqdNXfmeMcXRhj3g9XFGY=
github.com/evanw/esbuild v0.21.0/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
github.com/evanw/esbuild v0.23.1 h1:ociewhY6arjTarKLdrXfDTgy25oxhTZmzP8pfuBTfTA=
github.com/evanw/esbuild v0.23.1/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
Expand Down

0 comments on commit 55b41f8

Please sign in to comment.