Add js web stuff to landing page + documentation
This commit is contained in:
94
go/jsbundler/jsx.go
Normal file
94
go/jsbundler/jsx.go
Normal file
@@ -0,0 +1,94 @@
|
||||
// Solid JSX/TSX compilation (part of package jsbundler): compiles Solid JSX/TSX to
|
||||
// optimized Solid dom-expressions output (template cloning + fine-grained
|
||||
// updates) with a Go-native compiler — no Node, no Babel, no goja. The compiler
|
||||
// lives in compile_solid.go (parser) and compile_solid_gen.go (codegen);
|
||||
// segment.go supplies the top-level splitter it uses to find component
|
||||
// declarations for solid-refresh instrumentation.
|
||||
//
|
||||
// Compile is the prod path (SSR + release bundles); CompileDev adds solid-refresh
|
||||
// HMR instrumentation. Both are plain function calls — fast enough that the old
|
||||
// per-declaration incremental caching is gone. A small in-memory cache dedups
|
||||
// identical transforms within a process (e.g. a module served to several page
|
||||
// loads under HMR); there is no on-disk cache and no compiler bootstrap.
|
||||
package jsbundler
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
esbuild "github.com/evanw/esbuild/pkg/api"
|
||||
)
|
||||
|
||||
// cache dedups transforms by content within a process, so a module unchanged
|
||||
// across dev page reloads (or repeated in a build) isn't recompiled.
|
||||
var cache = struct {
|
||||
sync.RWMutex
|
||||
m map[string]string
|
||||
}{m: map[string]string{}}
|
||||
|
||||
// cacheKey keys a transform by filename + mode + source.
|
||||
func cacheKey(src, filename string, dev bool) string {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(filename))
|
||||
h.Write([]byte{0})
|
||||
if dev {
|
||||
h.Write([]byte{1})
|
||||
} else {
|
||||
h.Write([]byte{0})
|
||||
}
|
||||
h.Write([]byte{0})
|
||||
h.Write([]byte(src))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// Compile compiles one JSX/TSX source to Solid dom-expressions output (prod: no
|
||||
// HMR instrumentation). Results are cached by content for this process.
|
||||
func Compile(src, filename string) (string, error) { return compileCached(src, filename, false) }
|
||||
|
||||
// CompileDev is Compile with solid-refresh HMR instrumentation — the dev module
|
||||
// server's entry.
|
||||
func CompileDev(src, filename string) (string, error) { return compileCached(src, filename, true) }
|
||||
|
||||
func compileCached(src, filename string, dev bool) (string, error) {
|
||||
key := cacheKey(src, filename, dev)
|
||||
cache.RLock()
|
||||
if out, ok := cache.m[key]; ok {
|
||||
cache.RUnlock()
|
||||
return out, nil
|
||||
}
|
||||
cache.RUnlock()
|
||||
|
||||
out, err := compileSolidGo(src, filename, dev)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cache.Lock()
|
||||
cache.m[key] = out
|
||||
cache.Unlock()
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Plugin returns the esbuild OnLoad hook that Solid-compiles every .tsx/.jsx file
|
||||
// in the bundle graph (prod path). Plain .ts/.js files are left to esbuild.
|
||||
func Plugin() esbuild.Plugin {
|
||||
return esbuild.Plugin{
|
||||
Name: "solid-jsx",
|
||||
Setup: func(b esbuild.PluginBuild) {
|
||||
b.OnLoad(esbuild.OnLoadOptions{Filter: `\.(tsx|jsx)$`}, func(a esbuild.OnLoadArgs) (esbuild.OnLoadResult, error) {
|
||||
data, err := os.ReadFile(a.Path)
|
||||
if err != nil {
|
||||
return esbuild.OnLoadResult{}, err
|
||||
}
|
||||
out, err := Compile(string(data), filepath.Base(a.Path))
|
||||
if err != nil {
|
||||
return esbuild.OnLoadResult{}, err
|
||||
}
|
||||
loader := esbuild.LoaderJS
|
||||
return esbuild.OnLoadResult{Contents: &out, Loader: loader}, nil
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user