Files
Martino Ferrari c0f7e662be Testing
2026-06-24 01:39:15 +02:00

132 lines
4.2 KiB
Go

package main
import (
"fmt"
"os"
"path/filepath"
"github.com/evanw/esbuild/pkg/api"
)
func main() {
// Determine repo root.
// When invoked via `go generate` from web/, cwd is web/ so we look for go.mod
// to find the actual module root.
root, err := findModuleRoot()
if err != nil {
panic(err)
}
// Verify vendor files exist
vendorFiles := []string{
filepath.Join(root, "web", "vendor", "preact.mjs"),
filepath.Join(root, "web", "vendor", "preact-hooks.mjs"),
filepath.Join(root, "web", "vendor", "uplot.esm.js"),
filepath.Join(root, "web", "vendor", "uplot.css"),
filepath.Join(root, "web", "vendor", "echarts.esm.js"),
}
for _, f := range vendorFiles {
if _, err := os.Stat(f); os.IsNotExist(err) {
fmt.Fprintf(os.Stderr, "error: vendor file missing: %s\n", f)
fmt.Fprintf(os.Stderr, "Run the following to download vendor files:\n")
fmt.Fprintf(os.Stderr, " mkdir -p web/vendor\n")
fmt.Fprintf(os.Stderr, " curl -sL https://cdn.jsdelivr.net/npm/preact@10.24.3/dist/preact.module.js -o web/vendor/preact.mjs\n")
fmt.Fprintf(os.Stderr, " curl -sL https://cdn.jsdelivr.net/npm/preact@10.24.3/hooks/dist/hooks.module.js -o web/vendor/preact-hooks.mjs\n")
fmt.Fprintf(os.Stderr, " curl -sL https://cdn.jsdelivr.net/npm/uplot@1.6.32/dist/uPlot.esm.js -o web/vendor/uplot.esm.js\n")
fmt.Fprintf(os.Stderr, " curl -sL https://cdn.jsdelivr.net/npm/uplot@1.6.32/dist/uPlot.min.css -o web/vendor/uplot.css\n")
fmt.Fprintf(os.Stderr, " curl -sL https://cdn.jsdelivr.net/npm/echarts@5.5.1/dist/echarts.esm.min.js -o web/vendor/echarts.esm.js\n")
os.Exit(1)
}
}
// Clean + create dist
distDir := filepath.Join(root, "web", "dist")
os.RemoveAll(distDir)
os.MkdirAll(distDir, 0o755)
result := api.Build(api.BuildOptions{
EntryPoints: []string{filepath.Join(root, "web", "src", "main.tsx")},
Bundle: true,
Outdir: distDir,
Format: api.FormatESModule,
Target: api.ES2020,
JSX: api.JSXTransform,
JSXFactory: "h",
JSXFragment: "Fragment",
MinifyWhitespace: true,
MinifyIdentifiers: true,
MinifySyntax: true,
Alias: map[string]string{
"preact": filepath.Join(root, "web", "vendor", "preact.mjs"),
"preact/hooks": filepath.Join(root, "web", "vendor", "preact-hooks.mjs"),
"uplot": filepath.Join(root, "web", "vendor", "uplot.esm.js"),
"echarts": filepath.Join(root, "web", "vendor", "echarts.esm.js"),
},
Loader: map[string]api.Loader{
".css": api.LoaderCSS,
},
Splitting: false,
Write: true,
LogLevel: api.LogLevelInfo,
})
if len(result.Errors) > 0 {
for _, e := range result.Errors {
fmt.Fprintf(os.Stderr, "error: %s\n", e.Text)
}
os.Exit(1)
}
// Copy uPlot CSS and favicon
copyFile(filepath.Join(root, "web", "vendor", "uplot.css"), filepath.Join(distDir, "uplot.css"))
copyFile(filepath.Join(root, "web", "public", "favicon.svg"), filepath.Join(distDir, "favicon.svg"))
copyFile(filepath.Join(root, "web", "public", "favicon.svg"), filepath.Join(distDir, "favicon.ico"))
// Write index.html
html := `<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>uopi</title>
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="stylesheet" href="/uplot.css" />
<link rel="stylesheet" href="/main.css" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/main.js"></script>
</body>
</html>`
os.WriteFile(filepath.Join(distDir, "index.html"), []byte(html), 0o644)
fmt.Println("Frontend built successfully →", distDir)
}
func copyFile(src, dst string) {
data, err := os.ReadFile(src)
if err != nil {
return // Skip if missing
}
os.WriteFile(dst, data, 0o644)
}
// findModuleRoot walks up from cwd until it finds a go.mod file.
func findModuleRoot() (string, error) {
dir, err := os.Getwd()
if err != nil {
return "", err
}
for {
if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil {
return dir, nil
}
parent := filepath.Dir(dir)
if parent == dir {
return "", fmt.Errorf("go.mod not found in any parent directory")
}
dir = parent
}
}