fix(examples): render the dynamic example on @dynamic-labs v5 - #851
Merged
Conversation
|
Contributor
✅ E2E Dev Smoke — passing
4 passed · 0 failed · 0 skipped · 32s |
Contributor
E2E Examples — all passedAll examples passed in the latest run. |
Contributor
E2E Playground resultsDetails
📥 Download full HTML report (open the run → Artifacts → |
The example was `status: broken` and skipped by the e2e harness, so the @dynamic-labs v5 bump was never render-verified. It now builds, serves and passes the widget-smoke suite, and is back in the active set (18 examples). The old broken note blamed vite-plugin-env-compatible and prescribed swapping in vite-plugin-node-polyfills. The diagnosis was right — that plugin only substitutes `process.env.*` at build time, while the Dynamic SDK reads a bare `process` global (nextTick/versions/emit) and its own polyfills.js imports `buffer/index.js` — but the prescribed fix no longer works on its own. vite-plugin-node-polyfills advertises a Vite 8 peer range, yet aliases its own shims by bare specifier, and its exports map still carries legacy trailing-slash keys that resolve to files. Rolldown rejects those: Expecting folder to folder mapping. ".../vite-plugin-node-polyfills/package.json" should end with "/" 0.28.0 ships an identical exports map and fails the same way, so bumping the plugin does not help. Upstream fixes are open but unreleased (#161, #154; #158 and #140 report this error). A one-hook `resolveId` plugin resolves the three shims to their real files, which keeps rolldown out of the exports map — and becomes deletable once upstream ships. `vite dev` for this example is still broken: dependency pre-bundling resolves the plugin's injected banner in a separate plugin container this hook cannot reach. That path was equally broken before (`process is not defined` in both dev and build), and no CI job covers an example's dev server.
chybisov
force-pushed
the
fix/dynamic-example-v5
branch
from
August 21, 2026 12:48
3dc0631 to
c0d3728
Compare
Patch the shim references in nodePolyfills()' own returned config, before Vite merges it, instead of only intercepting the module graph. That is where the dependency pre-bundle alias maps and the injected banner come from, and pre-bundling resolves them in its own container — so a resolveId hook alone left `vite dev` failing on the same "Expecting folder to folder mapping". Alias values point at the shim directory rather than the file: aliases substitute by prefix, so a directory keeps both `buffer` and `buffer/index.js` resolvable. Import specifiers in the banner still get the file. Also move WalletHeader off MUI system props. MUI 9 no longer forwards `display`/`justifyContent`/`alignItems`/`borderBottom` on Box, so they leaked to the DOM — React logged "does not recognize the prop" for each and the header styling was silently lost. Using `sx` restores it and clears the last `tsc -b` errors in this example, which now type-checks clean. `vite dev`, `vite build` and `vite preview` all render the widget now.
#850 added `ws@>=7.0.0 <8.0.0` and `ws@>=8.0.0` overrides but never ran `pnpm dedupe`, so the lockfile still carried ws@7.5.13 alongside ws@8.21.3. The vulnerable copy stayed in the tree via @remix-run/dev and jayson (through isomorphic-ws), which is exactly what those overrides were meant to remove — the fix was only half-applied, and `pnpm dedupe --check` failed on main. `pnpm dedupe` collapses ws to a single 8.21.3 and the check passes again.
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.
Which Linear task is linked to this PR?
Follow-up to #847 — no Linear task.
Why was it implemented this way?
#847 bumped
@dynamic-labs/*from 4.92.3 to 5.3.1, butexamples/dynamicwasstatus: brokenine2e/examples.json, so the harness skipped it and the v5 major was neverrender-verified. This makes the example work and returns it to the active set — 18 examples.
What was actually broken
The old
brokenReasonblamedvite-plugin-env-compatibleand prescribed swapping invite-plugin-node-polyfills. The diagnosis was right:vite-plugin-env-compatibleonlysubstitutes
process.env.*at build time, while the Dynamic SDK reads a bareprocessglobaland its own
polyfills.jsimportsbuffer/index.js. Confirmed from the built bundle:But the prescribed fix no longer works on its own.
vite-plugin-node-polyfillsadvertises aVite 8 peer range (
^2 || … || ^8), yet aliases its own shims by bare specifier, and itsexports map still carries legacy trailing-slash keys (
"./shims/process/") that resolve to files.Rolldown validates those strictly where Vite 7's rollup ignored them:
Things I ruled out along the way:
the same shim files, and fails the same way. Bumping does not help.
bufferpackage does build — the SDK's
polyfills.jsassignswindow.global/window.Bufferitself —but the free
processglobal is still undefined at runtime.#161 (build root shims
export) and #154 (use
oxc when Rolldown is detected), with
#158 and
#140 reporting this
exact error.
The fix
nodePolyfills()is kept — it is what actually injects the shims. Its bare shim references areresolved to real files in the two places that need it, because dependency pre-bundling runs its
own resolver:
resolveIdhook. The regex is anchored so it matches onlybuffer/global/process, theirnode:forms, their subpaths (buffer/index.js), andthe plugin's own
vite-plugin-node-polyfills/shims/*— and not lookalikes such assome-pkg/process,processing, ormy-buffer(unit-tested).pre-bundle alias maps and the injected banner come from, and a
resolveIdhook cannot reachthem — which is why
vite devstayed broken until this was added.Alias values point at the shim directory rather than the file: aliases substitute by prefix, so
a directory keeps both
bufferandbuffer/index.jsresolvable. Import specifiers in the bannerstill get the file.
Both are deletable as soon as upstream ships; the comment in the config says so.
MUI system props on Box
Fixing dev mode surfaced a second, real bug.
WalletHeaderpasseddisplay,justifyContent,alignItemsandborderBottomas directBoxprops. MUI 9 no longer forwardsthose, so they leaked to the DOM — React logged "does not recognize the prop" for each, and the
header styling was silently lost. Moving them into
sxrestores the layout and clears thelast
tsc -berrors here, soexamples/dynamicnow type-checks clean.Bundled in:
pnpm dedupe#850 added
ws@>=7.0.0 <8.0.0andws@>=8.0.0overrides but never ranpnpm dedupe, so thelockfile still carried ws@7.5.13 alongside ws@8.21.3. The vulnerable copy stayed in the tree
via
@remix-run/devandjayson(throughisomorphic-ws) — precisely what those overrides weremeant to remove, so that security fix was only half-applied, and
pnpm dedupe --checkfailed onmain. Deduping collapseswsto a single8.21.3; the diff is 27 lines.vite-plugin-node-polyfillsmoves todevDependenciesat^0.26.0, matching the twelve otherexamples that already use it, and
vite-plugin-env-compatibleis dropped.Visual showcase (Screenshots or Videos)
examples/dynamicrenders the widget alongside Dynamic's own connect button, in bothvite devandvite preview. Page text from a headless load:Console is clean — no
process is not defined, no app errors.Verification
examples/dynamicwidget-smokeexamples/dynamicvite devexamples/dynamictsc -bpnpm test:examplespnpm buildpnpm check(Biome)pnpm check:typespnpm check:circular-depspnpm install --frozen-lockfilepnpm dedupe --checkmainbefore this PR)Also updated the profile enumeration in
e2e/tests/profiles/widget-smoke.spec.ts— the standardprofile is now 14, not 13.
Not addressed here
The same MUI
TS2769overload errors still failtsc -binprivy,connectkitandreown,from the same system-props-on-
Boxpattern. That is long-standing and why those examples carrybuildCmd: vite-build, which skipstsc.dynamicis fixed because its errors were in the fileI had to touch anyway; the other three are a separate sweep.
Checklist before requesting a review