fix(vite-plugin): hydrate islands exported by name#711
Draft
romain-pm wants to merge 1 commit into
Draft
Conversation
`insert-filename` only attached the hydration metadata (`__filename`) to the
default export of a `*.client.{jsx,tsx}` file. A component exported by name
built and server-rendered fine, but the browser then requested
`<module>/undefined.js` and the island never hydrated — silently, with an
interactive form degrading to a native submit.
Every export of a client file is now tagged, with the export name alongside
the filename, so `<Island>` can tell the loader which binding to pick up
(`data-export`, omitted for default exports so older bundles keep working).
A component that carries no metadata at all — declared outside a client file,
or reached through an `export { … }` list — now throws at render with a
message naming it, instead of letting `undefined.js` reach the browser.
Verified on a Jahia 8.2 instance: a named-export island hydrates and stays
interactive, the two default-export islands of the test module still hydrate,
and a metadata-less component fails the render with the new message.
Closes #706
🦜 Chachalog
|
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #706 — part of EPIC #698 (developer experience).
The bug
Builds clean. Server-renders clean. In the browser the island requests
/modules/<module>/undefined.js, the import fails, and the component never hydrates — for a form, the submit silently degrades to a native GET. The only clue is a console error.insert-filenameattaches the hydration metadata (__filename) toExportDefaultDeclarationnodes only, soComponent.__filenameisundefinedfor a named export and<Island>interpolates it straight into the URL.Change
Three coordinated pieces, all in this monorepo, released together:
vite-plugintags every export of a*.client.{jsx,tsx}file —export function,export const,export class, and the existing default — with__filenameand the new__exportName. Declarations can't be wrapped in an expression, so named exports are tagged by a statement appended after them. Descriptors areconfigurableso a component exported twice (export const Foo = …; export default Foo;) is tagged twice instead of throwing.Islandemitsdata-export(omitted for default exports, so nothing changes in existing markup) and now throws when a component carries no metadata at all, naming it and explaining which export forms are supported.data-export, falling back todefault— so islands built with an older plugin keep working.export { … }lists and re-exports remain unsupported: they cannot be tagged reliably, and they now land in the fail-fast path instead of producingundefined.js.Verification
Fixtures (
yarn workspace @jahia/vite-plugin test, 2 tests): a newnamed.client.tsxexporting two components by name is mounted alongside the existing default-export island; the test asserts the exact(__filename, __exportName)triples in the server bundle and that the client bundle really exposes both names. Snapshots regenerated.E2E: the test module gains a named-export island, and the hydration spec gains a case asserting it hydrates and stays interactive, with a
cy.interceptthat fails the test if anything ever requestsundefined.js.Live on Jahia 8.2:
data-export="SampleNamedExportReact", hydrates, and increments on click (5 → 6);data-exporton them);<Island> received a component without hydration metadata: NotAClientComponent…instead of reaching the browser.Note for the reviewer
Modules must be rebuilt with the matching plugin version to use named exports; already-deployed modules are unaffected (no
data-export→ loader falls back todefault).