Precompress webclient assets with precompress util. This cuts our css and js build sizes to about 1/3 of non-compressed size. Similar compression done on tsconnect and adminhttp assets. Updates #10261 Signed-off-by: Sonia Appasamy <sonia@tailscale.com>main
parent
97f8577ad2
commit
e5e5ebda44
@ -0,0 +1,95 @@ |
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// The build-webclient tool generates the static resources needed for the
|
||||
// web client (code at client/web).
|
||||
//
|
||||
// # Running
|
||||
//
|
||||
// Meant to be invoked from the tailscale/web-client-prebuilt repo when
|
||||
// updating the production built web client assets. To run it manually,
|
||||
// you can use `./tool/go run ./misc/build-webclient`
|
||||
package main |
||||
|
||||
import ( |
||||
"flag" |
||||
"fmt" |
||||
"log" |
||||
"os" |
||||
"os/exec" |
||||
"path/filepath" |
||||
|
||||
"tailscale.com/util/precompress" |
||||
) |
||||
|
||||
var ( |
||||
outDir = flag.String("outDir", "build/", "path to output directory") |
||||
) |
||||
|
||||
func main() { |
||||
flag.Parse() |
||||
|
||||
// The toolDir flag is relative to the current working directory,
|
||||
// so we need to resolve it to an absolute path.
|
||||
toolDir, err := filepath.Abs("./tool") |
||||
if err != nil { |
||||
log.Fatalf("Cannot resolve tool-dir: %v", err) |
||||
} |
||||
|
||||
if err := build(toolDir, "client/web"); err != nil { |
||||
log.Fatalf("%v", err) |
||||
} |
||||
} |
||||
|
||||
func build(toolDir, appDir string) error { |
||||
if err := os.Chdir(appDir); err != nil { |
||||
return fmt.Errorf("Cannot change cwd: %w", err) |
||||
} |
||||
|
||||
if err := yarn(toolDir); err != nil { |
||||
return fmt.Errorf("install failed: %w", err) |
||||
} |
||||
|
||||
if err := yarn(toolDir, "lint"); err != nil { |
||||
return fmt.Errorf("lint failed: %w", err) |
||||
} |
||||
|
||||
if err := yarn(toolDir, "build", "--outDir="+*outDir, "--emptyOutDir"); err != nil { |
||||
return fmt.Errorf("build failed: %w", err) |
||||
} |
||||
|
||||
var compressedFiles []string |
||||
if err := precompress.PrecompressDir(*outDir, precompress.Options{ |
||||
ProgressFn: func(path string) { |
||||
log.Printf("Pre-compressing %v\n", path) |
||||
compressedFiles = append(compressedFiles, path) |
||||
}, |
||||
}); err != nil { |
||||
return fmt.Errorf("Cannot precompress: %w", err) |
||||
} |
||||
|
||||
// Cleanup pre-compressed files.
|
||||
for _, f := range compressedFiles { |
||||
if err := os.Remove(f); err != nil { |
||||
log.Printf("Failed to cleanup %q: %v", f, err) |
||||
} |
||||
// Removing intermediate ".br" version, we use ".gz" asset.
|
||||
if err := os.Remove(f + ".br"); err != nil { |
||||
log.Printf("Failed to cleanup %q: %v", f+".gz", err) |
||||
} |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func yarn(toolDir string, args ...string) error { |
||||
args = append([]string{"--silent", "--non-interactive"}, args...) |
||||
return run(filepath.Join(toolDir, "yarn"), args...) |
||||
} |
||||
|
||||
func run(name string, args ...string) error { |
||||
cmd := exec.Command(name, args...) |
||||
cmd.Stdout = os.Stdout |
||||
cmd.Stderr = os.Stderr |
||||
return cmd.Run() |
||||
} |
||||
Loading…
Reference in new issue