Skip to content

🍕 Clarify _client-init.js component-mounting semantics in docs#250

Merged
jjpaulino merged 1 commit into
masterfrom
jordan/fix-client-init-mounting-docs
May 15, 2026
Merged

🍕 Clarify _client-init.js component-mounting semantics in docs#250
jjpaulino merged 1 commit into
masterfrom
jordan/fix-client-init-mounting-docs

Conversation

@jjpaulino
Copy link
Copy Markdown
Member

Summary

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 and confuses readers about the precise nature of the Vite improvement.

What _client-init.js actually does

Per lib/cmd/compile/_client-init.js, mountComponentModules():

  1. Iterates every .client key in window.modules
  2. Calls window.require(key) on each — this executes the module body and walks its full dependency graph, regardless of DOM presence
  3. Then runs document.querySelectorAll([data-uri*="_components/<name>/"]) and only calls the exported controller via tryToMount(controllerFn, el, name) for elements that actually exist

So the mount invocation itself is DOM-gated — what isn't gated is module evaluation and dependency resolution.

What vite-bootstrap.js does (the actual improvement)

Scans the DOM first and skips the dynamic import() entirely when no matching element exists. Neither the module body nor any of its transitive dependencies execute for components absent from the page.

Files changed

  • CLAY-VITE.md — three table cells in §4a (architecture summary), §4d (concern matrix), and §11 (clay compile vs clay vite comparison)
  • BUNDLER-COMPARISON.md — one inline diagram caption in §1

The mermaid diagrams in CLAY-VITE.md and CLAYCLI-ROLLOUT-CHANGES.md already use the more precise "calls window.require(key) for every .client / regardless of DOM presence" wording and are left as-is.

Follow-up

sites/CLAYCLI-ROLLOUT-CHANGES.md (in nymag/sites) has the same overstated wording in its concern matrix; will be fixed in a separate sites PR.

Test plan

  • npm test — lint + 435 jest tests pass locally
  • Spot-check rendered tables in the GitHub diff view to confirm Markdown layout is intact

Made with Cursor

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/<name>/"] / [data-uri$="_components<name>"]
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 <cursoragent@cursor.com>
@coveralls
Copy link
Copy Markdown

Coverage Status

coverage: 86.85%. remained the same — jordan/fix-client-init-mounting-docs into master

@jjpaulino jjpaulino merged commit beeb89d into master May 15, 2026
6 checks passed
@jjpaulino jjpaulino deleted the jordan/fix-client-init-mounting-docs branch May 15, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants