fix: resolve dev hydration failure, add CI - #2
Merged
Conversation
elkjs ----- `elkjs/lib/elk.bundled.js` is UMD. In dev the browser was being served it raw, so the ES import found no `default` export and hydration died with a 500 page on every route. SSR output was always correct, which made it look intermittent. The chain is @comark/vue's Mermaid component -> beautiful-mermaid -> elkjs. The earlier `beautiful-mermaid > elkjs/lib/elk.bundled.js` entry did produce an optimized chunk, but the optimizer keys it by that chain string while the specifier beautiful-mermaid actually imports is the bare `elkjs/lib/elk.bundled.js` -- so the import was never rewritten to it. Matching the specifier verbatim requires elkjs to resolve from the layer root, hence the direct dependency on a package nothing here imports. Verified end to end: @comark/vue now imports the optimized beautiful-mermaid chunk, which imports the optimized elkjs chunk (a proper CJS->ESM conversion with no external imports). Console is clean across a fresh tab, repeated reloads, cross-page navigation and a dev-server restart against an existing tab -- the case that previously resurfaced it from a stale module graph. Footer ------ Drop the `(c)` from the default credits line, restoring the wording the sites had before the footer was made configurable. CI -- Add a workflow mirroring comark-cms: install, prepare, typecheck, build. No lint or test steps -- this package has neither. The build covers the playground, which exercises content pages, the landing route, OG images and the generated ISR route rules.
The `elkjs` direct dependency and its `optimizeDeps.include` entry did nothing. Evidence from the dev dep cache: beautiful-mermaid -> .pnpm/beautiful-mermaid@1.1.3/…/index.js elkjs/lib/elk.bundled.js -> .pnpm/elkjs@0.12.0/…/elk.bundled.js beautiful-mermaid declares `elkjs: ^0.11.0` and resolves 0.11.1, so the entry (0.12.0 from the layer root) pointed at a different file than the one beautiful-mermaid imports. It could not affect that chunk: the optimized beautiful-mermaid.js inlines elkjs 0.11.1 and imports nothing, while elkjs_lib_elk__bundled__js.js sat orphaned at 2.5 MB. So what actually fixed hydration was removing the *old* `beautiful-mermaid > elkjs/lib/elk.bundled.js` entry, which did resolve to bm's own copy, collided with it and split elkjs back out where the browser got raw UMD. The replacement only looked load-bearing because the version mismatch kept it from colliding — an invariant that would break the moment beautiful-mermaid widens its elkjs range. Dropping both leaves `['beautiful-mermaid', 'motion-v']`, saves a needless 1.5 MB dependency for every consumer of the layer plus 2.5 MB of cold-start optimizer work, and removes the latent trap. The comment now says why an elkjs entry must not be re-added. Verified on a cold dep cache in headless Chromium: all four playground routes hydrate, the mermaid diagram renders, and console/exceptions/ failed-requests are empty on both cold and warm cache. prepare, typecheck and build pass. Also: - app.config.ts credits comment still said "All rights reserved." - CI: `permissions: contents: read`, concurrency with cancel-in-progress, explicit `--frozen-lockfile`, job renamed `test` -> `ci` (no tests here) - trailing newlines in pnpm-workspace.yaml and 1.introduction.md
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.
elkjs / dev hydration
elkjs/lib/elk.bundled.jsis UMD. In dev the browser was being served it raw,so the ES import found no
defaultexport and hydration died with a 500 pageon every route. SSR output was always correct, which made it look intermittent.
The chain is @comark/vue's Mermaid component -> beautiful-mermaid -> elkjs. The
culprit was the
beautiful-mermaid > elkjs/lib/elk.bundled.jsentry inoptimizeDeps.include: it resolved to the same file beautiful-mermaid imports,which made the optimizer split elkjs out of beautiful-mermaid's chunk into a
second entry the browser then had to resolve itself — and got the raw UMD.
The fix is to declare only
beautiful-mermaidand let the optimizer inlineelkjs into its chunk, so the raw UMD is never served. Verified against the dev
dep cache:
beautiful-mermaid.jscontains elkjs inline and imports nothing;there is no separate elkjs chunk.
Checked on a cold dep cache in headless Chromium — all four playground routes
hydrate, the mermaid diagram renders, and console errors, uncaught exceptions
and failed requests are all empty, on both a cold and a warm cache.
CI
Add a workflow mirroring comark-cms: install, prepare, typecheck, build. No lint
or test steps -- this package has neither, so the job is named
cirather thantest. Runs withpermissions: contents: read, a concurrency group that cancelssuperseded runs, and an explicit
--frozen-lockfile. The build covers theplayground, which exercises content pages, the landing route, OG images and the
generated ISR route rules.
Footer
Credits default drops to
© ${year} ${owner}.— no "Copyright" prefix, no"All rights reserved." (legally inert under Berne). README,
app.config.ts,nuxt.schema.tsandAppFooter.vueall updated to agree.Playground
index.mdusesnavigation: falseso Home is no longer a sidebar entry.## Code blockssection from1.introduction.md;2.installation.mdalready covers bash/ts code blocks and the mermaiddiagram, which is what exercises the elkjs path above.
ownerisVercel, Inc.Dependencies
Routine bumps carried along: nuxt 4.5.1, satori 0.29, @nuxtjs/sitemap 8.3,
@nuxtjs/robots 6.1.3, nuxt-og-image 6.7.4, nuxt-seo-utils 8.3.2, exsolve 1.1,
iconify collections, and the h3 override to ^1.15.11. Satori renders OG images
at request time, so the build compiles them but does not render them — worth an
eyeball on a preview deploy.