mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-31 08:11:32 +01:00 
			
		
		
		
	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>
		
			
				
	
	
		
			96 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // 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()
 | |
| }
 |