Phase 6
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
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"))
|
||||
|
||||
// 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" 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user