add bundler stuff

This commit is contained in:
2026-07-08 16:59:00 -04:00
parent 2a5fbffaa2
commit ba3d87c27f
12 changed files with 425 additions and 70 deletions

View File

@@ -0,0 +1,96 @@
package bundler
import (
"os"
"path/filepath"
"strings"
"testing"
)
// TestCrossTreeJSBundle proves the bundler resolves the shared kit across the
// app/kjol tree boundary: a temp app entry imports @ui/Buttons, which pulls the
// real kjol web/kit (Buttons -> ./Icons -> @appgen/faIcons stub) and the solid
// runtime from web/runtime. If the alias plugin, merged vendor manifest, and
// multi-dir NodePaths all work, esbuild produces a non-empty bundle.
func TestCrossTreeJSBundle(t *testing.T) {
webAbs, err := filepath.Abs(filepath.Join("..", "..", "web"))
if err != nil {
t.Fatal(err)
}
if _, err := os.Stat(filepath.Join(webAbs, "kit", "Buttons.tsx")); err != nil {
t.Skipf("kjol web kit not present (%v)", err)
}
app := t.TempDir()
gen := t.TempDir()
out := t.TempDir()
if err := os.MkdirAll(filepath.Join(app, "src"), 0o755); err != nil {
t.Fatal(err)
}
entry := filepath.Join(app, "src", "app.ts")
entrySrc := "import * as Buttons from \"@ui/Buttons\";\n" +
"(globalThis as any).__kit = Buttons;\n"
if err := os.WriteFile(entry, []byte(entrySrc), 0o644); err != nil {
t.Fatal(err)
}
// Stub the app-owned generated FA registry that Icons.tsx imports via @appgen.
if err := os.WriteFile(filepath.Join(gen, "faIcons.ts"), []byte("export const FA_ICONS = {};\n"), 0o644); err != nil {
t.Fatal(err)
}
Configure(Config{AppFrontend: app, WebDir: webAbs, Output: out, GenTSDir: gen})
if _, err := bundleJSEntry(entry, "app.test.js"); err != nil {
t.Fatalf("cross-tree bundle failed: %v", err)
}
data, err := os.ReadFile(filepath.Join(out, "app.test.js"))
if err != nil {
t.Fatalf("no output bundle: %v", err)
}
if len(data) == 0 {
t.Fatal("empty bundle")
}
t.Logf("cross-tree bundle produced %d bytes", len(data))
}
// TestCrossTreeCSS confirms the CSS pipeline compiles with the kit tree scanned
// for utility candidates across the boundary (WebDir set) without error, and
// that an app-side utility class makes it into the output.
func TestCrossTreeCSS(t *testing.T) {
webAbs, err := filepath.Abs(filepath.Join("..", "..", "web"))
if err != nil {
t.Fatal(err)
}
if _, err := os.Stat(filepath.Join(webAbs, "kit")); err != nil {
t.Skipf("kjol web kit not present (%v)", err)
}
app := t.TempDir()
out := t.TempDir()
if err := os.MkdirAll(filepath.Join(app, "css"), 0o755); err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(filepath.Join(app, "src"), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(app, "css", "style.css"), []byte("@import \"tailwindcss\";\n"), 0o644); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(app, "src", "app.ts"), []byte("export const x = `<div class=\"p-4\"></div>`;\n"), 0o644); err != nil {
t.Fatal(err)
}
Configure(Config{AppFrontend: app, WebDir: webAbs, Output: out})
if _, err := compileCSSBundle("test", []string{"../src/**/*.ts"}, "test.css"); err != nil {
t.Fatalf("cross-tree css compile failed: %v", err)
}
data, err := os.ReadFile(filepath.Join(out, "test.css"))
if err != nil {
t.Fatalf("no output css: %v", err)
}
if !strings.Contains(string(data), "padding") {
t.Errorf("expected the app utility .p-4 to compile into the output")
}
t.Logf("cross-tree css produced %d bytes", len(data))
}