Files
kjol/go/webbundler/alias.go

77 lines
2.3 KiB
Go

package webbundler
import (
"fmt"
"os"
"path/filepath"
"strings"
esbuild "github.com/evanw/esbuild/pkg/api"
)
// aliasRoots maps the framework import prefixes to absolute filesystem roots:
//
// @ui/* -> kjol web kit (shared Solid components)
// @kjol/* -> kjol web root (auth, utils, hooks, ssr, env.ts, ...)
// @appgen/* -> the app's generated dir (faIcons registry etc. — app-owned)
//
// In single-tree mode @ui/@kjol resolve back under the app frontend.
func aliasRoots() map[string]string {
abs := func(p string) string { a, _ := filepath.Abs(p); return a }
return map[string]string{
"@ui": abs(uikitDir()),
"@kjol": abs(webRoot()),
"@appgen": abs(genTSDir),
}
}
// resolveAlias turns "<root>/<rest>" into a concrete file, probing the usual
// TS/JS extensions and index files when the specifier is extensionless.
func resolveAlias(root, rest string) (string, bool) {
base := filepath.Join(root, filepath.FromSlash(rest))
var cands []string
if filepath.Ext(base) != "" {
cands = append(cands, base)
} else {
for _, e := range []string{".tsx", ".ts", ".jsx", ".js"} {
cands = append(cands, base+e)
}
for _, e := range []string{".tsx", ".ts", ".jsx", ".js"} {
cands = append(cands, filepath.Join(base, "index"+e))
}
}
for _, c := range cands {
if fi, err := os.Stat(c); err == nil && !fi.IsDir() {
return c, true
}
}
return "", false
}
// aliasPlugin resolves @ui / @kjol / @appgen imports to absolute paths across the
// app and kjol web trees. It sits before the vendor resolvers; the Solid
// compiler's OnLoad then compiles any .tsx/.jsx it points at.
func aliasPlugin() esbuild.Plugin {
roots := aliasRoots()
return esbuild.Plugin{
Name: "kjol-alias",
Setup: func(b esbuild.PluginBuild) {
b.OnResolve(esbuild.OnResolveOptions{Filter: `^@(ui|kjol|appgen)/`}, func(a esbuild.OnResolveArgs) (esbuild.OnResolveResult, error) {
slash := strings.IndexByte(a.Path, '/')
if slash < 0 {
return esbuild.OnResolveResult{}, nil
}
prefix, rest := a.Path[:slash], a.Path[slash+1:]
root, ok := roots[prefix]
if !ok {
return esbuild.OnResolveResult{}, nil
}
if p, ok := resolveAlias(root, rest); ok {
return esbuild.OnResolveResult{Path: p}, nil
}
return esbuild.OnResolveResult{}, fmt.Errorf("kjol-alias: cannot resolve %q under %s", a.Path, root)
})
},
}
}