From a73f1189ed773d41b9cc20e414ed0fda2cfcefb7 Mon Sep 17 00:00:00 2001 From: Jordan Paulino Date: Fri, 15 May 2026 13:49:14 -0400 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8D=95=20Clarify=20=5Fclient-init.js?= =?UTF-8?q?=20component-mounting=20semantics=20in=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several places in CLAY-VITE.md and BUNDLER-COMPARISON.md described the legacy Browserify component loader as "mounts every .client module loaded — no DOM check" or "DOM or not". That overstates what _client-init.js actually does. Per lib/cmd/compile/_client-init.js, mountComponentModules() iterates every .client key in window.modules and calls window.require(key) on each — which executes the module body and walks its dependency graph regardless of DOM presence — but the exported controller function is only invoked via tryToMount() for elements matching the [data-uri*="_components//"] / [data-uri$="_components"] selectors. So the mount call itself IS DOM-gated; what isn't gated is module evaluation. The Vite improvement is therefore narrower but still real: vite-bootstrap scans the DOM first and skips the dynamic import() entirely if no matching element exists, so neither the module body nor any of its transitive dependencies execute. Updated all four prose locations to reflect this; the mermaid diagrams already used the more precise "calls window.require(key) for every .client / regardless of DOM presence" wording and were left as-is. Co-authored-by: Cursor --- BUNDLER-COMPARISON.md | 4 +++- CLAY-VITE.md | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/BUNDLER-COMPARISON.md b/BUNDLER-COMPARISON.md index 9c41158..2054220 100644 --- a/BUNDLER-COMPARISON.md +++ b/BUNDLER-COMPARISON.md @@ -45,7 +45,9 @@ Browserify + Babel (30–60 s) ▼ _prelude.js / _postlude.js ← shipped to every page _registry.json + _ids.json ← opaque numeric dep graph -_client-init.js ← mounts every .client module loaded, DOM or not +_client-init.js ← calls window.require() on every .client module + (runs body + deps even if no DOM element exists); + controller invocation itself is DOM-gated ``` ### Problems diff --git a/CLAY-VITE.md b/CLAY-VITE.md index 03bda00..486744f 100644 --- a/CLAY-VITE.md +++ b/CLAY-VITE.md @@ -259,7 +259,7 @@ flowchart LR | **JS tool** | Browserify + Babel (megabundles) | Vite (Rollup 4 + manualChunks) | 🔄 Replaced | | **CSS tool** | Gulp + PostCSS 7 | PostCSS 8 programmatic API | 🔄 Replaced; same plugin ecosystem | | **Module graph** | `_registry.json` + `_ids.json` | `_manifest.json` (human-readable) | ⚠️ Different format; same purpose | -| **Component loader** | `_client-init.js` — mounts every `.client` module loaded | `vite-bootstrap.js` — mounts only when DOM element present | ✅ Better; avoids dead code execution | +| **Component loader** | `_client-init.js` — calls `window.require()` on every `.client` module (executing its body and dependency graph), then DOM-checks before invoking the exported controller | `vite-bootstrap.js` — scans the DOM first; only `import()`s a `.client` module if its element exists | ✅ Better; module body never executes for components absent from the page | | **JS output** | Per-component files + alpha-bucket dep files | Dynamic import splits + `chunks/` shared deps | ✅ Better; shared deps cached once | ### 4b. JS module system architecture @@ -339,7 +339,7 @@ flowchart TB | Concern | `clay compile` | `clay vite` | Why it matters | |---|---|---|---| | **Module registry** | Runtime: `window.modules` built as scripts evaluate | Build-time: `_manifest.json` written once | Old: any code could `window.require()` at any time. New: all wiring is static. | -| **Component mounting** | `_client-init.js` mounts every loaded `.client` module, DOM or not | `vite-bootstrap.js` scans DOM; only imports a component if its element exists | New: no dead component code execution | +| **Component mounting** | `_client-init.js` calls `window.require()` on every `.client` (running its body and dep graph) before DOM-gating the controller invocation | `vite-bootstrap.js` scans the DOM first; only imports a component if its element exists | New: no module body or transitive imports run for components absent from the page | | **Edit-mode aggregator** | `window.modules` registry | `_kiln-edit-init.js` pre-registers all model/kiln files on `window.kiln.componentModels` | New: explicit pre-wiring, backward compatible | | **Shared deps** | Alpha-bucketed dep files (`_deps-a.js`…) — static filenames | Named content-hashed chunks in `public/js/chunks/` | New: unchanged chunks stay cached across deploys | | **Global scripts** | Individual `