add bundler stuff
This commit is contained in:
@@ -15,32 +15,43 @@ type VendorManifest struct {
|
||||
Entrypoints map[string]string `json:"entrypoints"`
|
||||
}
|
||||
|
||||
// loadVendorManifest reads frontend/vendor/vendor.json — the single place that
|
||||
// declares the exact entrypoint file for every bundled vendored package.
|
||||
func loadVendorManifest(vendorDir string) (map[string]string, error) {
|
||||
data, err := os.ReadFile(filepath.Join(vendorDir, "vendor.json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// loadVendorManifest reads and merges vendor.json from every vendor dir (kjol
|
||||
// runtime first, app vendor second), returning spec -> ABSOLUTE entrypoint path.
|
||||
// Higher-precedence dirs win on conflict, so the shared solid-js always resolves
|
||||
// to the kjol runtime copy (a split reactive instance silently breaks effects).
|
||||
// A missing vendor.json in a dir is skipped.
|
||||
func loadVendorManifest(vendorDirs []string) (map[string]string, error) {
|
||||
abs := map[string]string{}
|
||||
for _, dir := range vendorDirs {
|
||||
data, err := os.ReadFile(filepath.Join(dir, "vendor.json"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
var m VendorManifest
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return nil, fmt.Errorf("parsing %s/vendor.json: %w", dir, err)
|
||||
}
|
||||
for spec, rel := range m.Entrypoints {
|
||||
if _, exists := abs[spec]; exists {
|
||||
continue // earlier (higher-precedence) dir wins
|
||||
}
|
||||
p, _ := filepath.Abs(filepath.Join(dir, filepath.FromSlash(rel)))
|
||||
abs[spec] = filepath.ToSlash(p)
|
||||
}
|
||||
}
|
||||
var m VendorManifest
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return nil, fmt.Errorf("parsing vendor.json: %w", err)
|
||||
}
|
||||
return m.Entrypoints, nil
|
||||
return abs, nil
|
||||
}
|
||||
|
||||
// vendorManifestPlugin resolves bare imports from the vendor manifest: a package
|
||||
// listed in vendor.json resolves to its pinned entrypoint file, bypassing the
|
||||
// package's own `exports` map (which mis-resolves — e.g. solid-js's bare core to
|
||||
// its SSR build, where effects are no-ops). Subpath imports of a vendored package
|
||||
// (e.g. pdfjs-dist/build/pdf.worker.min.mjs) resolve to the real file via
|
||||
// NodePaths; anything not vendored is left external for the import map.
|
||||
func vendorManifestPlugin(vendorDir string, entrypoints map[string]string) esbuild.Plugin {
|
||||
abs := make(map[string]string, len(entrypoints))
|
||||
for spec, rel := range entrypoints {
|
||||
p, _ := filepath.Abs(filepath.Join(vendorDir, filepath.FromSlash(rel)))
|
||||
abs[spec] = filepath.ToSlash(p)
|
||||
}
|
||||
// vendorManifestPlugin resolves bare imports from the merged vendor manifest: a
|
||||
// package listed in a vendor.json resolves to its pinned (absolute) entrypoint,
|
||||
// bypassing the package's own `exports` map (which mis-resolves — e.g. solid-js's
|
||||
// bare core to its SSR build, where effects are no-ops). Subpath imports of a
|
||||
// vendored package resolve to the real file via NodePaths; anything not vendored
|
||||
// is left external for the import map.
|
||||
func vendorManifestPlugin(entrypoints map[string]string, vendorDirs []string) esbuild.Plugin {
|
||||
return esbuild.Plugin{
|
||||
Name: "vendor-manifest",
|
||||
Setup: func(build esbuild.PluginBuild) {
|
||||
@@ -49,10 +60,10 @@ func vendorManifestPlugin(vendorDir string, entrypoints map[string]string) esbui
|
||||
if args.Kind == esbuild.ResolveEntryPoint || filepath.IsAbs(args.Path) || strings.HasPrefix(args.Path, ".") || strings.ContainsRune(args.Path, '?') {
|
||||
return esbuild.OnResolveResult{}, nil
|
||||
}
|
||||
if target, ok := abs[args.Path]; ok {
|
||||
if target, ok := entrypoints[args.Path]; ok {
|
||||
return esbuild.OnResolveResult{Path: target}, nil // pinned entrypoint
|
||||
}
|
||||
if vendorHasPackage(vendorDir, args.Path) {
|
||||
if vendorHasPackage(vendorDirs, args.Path) {
|
||||
return esbuild.OnResolveResult{}, nil // subpath of a vendored pkg -> NodePaths
|
||||
}
|
||||
return esbuild.OnResolveResult{External: true}, nil // not vendored -> import map
|
||||
@@ -62,15 +73,20 @@ func vendorManifestPlugin(vendorDir string, entrypoints map[string]string) esbui
|
||||
}
|
||||
|
||||
// vendorHasPackage reports whether a bare specifier maps to a package directory
|
||||
// under vendorDir, honouring @scope/name.
|
||||
func vendorHasPackage(vendorDir, spec string) bool {
|
||||
// under any vendor dir, honouring @scope/name.
|
||||
func vendorHasPackage(vendorDirs []string, spec string) bool {
|
||||
parts := strings.Split(spec, "/")
|
||||
pkg := parts[0]
|
||||
if strings.HasPrefix(pkg, "@") && len(parts) > 1 {
|
||||
pkg = pkg + "/" + parts[1]
|
||||
}
|
||||
info, err := os.Stat(filepath.Join(vendorDir, filepath.FromSlash(pkg)))
|
||||
return err == nil && info.IsDir()
|
||||
for _, dir := range vendorDirs {
|
||||
info, err := os.Stat(filepath.Join(dir, filepath.FromSlash(pkg)))
|
||||
if err == nil && info.IsDir() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// assetURLPlugin implements a generic `import url from "<path>?url"`: the
|
||||
|
||||
Reference in New Issue
Block a user