test(worker): prove Vite-equivalent Web Worker parity - #2892
Conversation
|
/bigbonk review for issues |
commit: |
|
There was a problem hiding this comment.
Review: fix(build): preserve Web Worker asset semantics
I reviewed the diff, ran the relevant Vitest suites (import-meta-url, image-imports, static-image-emission worker case — all green), and type-checked the vinext package. The change is well-scoped and correct. No blocking issues.
What's right
isImportMetaUrlBaseNode(import-meta-url.ts) correctly recognizes Vite's coerced worker base"" + import.meta.url(empty-stringLiteralon the left,import.meta.urlchain on the right) and skips rewriting it, while still descending into the firstnew URL()argument. This is the precise fix for thefile:///_next/static/...worker URLs. The narrow structural match (only"" + <import.meta.url>, operator+, left literal"") avoids over-matching.- Worker asset emission (
index.tsload) — theisWorkerbranch usesthis.emitFilebecause the sharedwriteBundlethat writes static images only runs for theclientenvironment. Without this, worker-referenced images would never be written. Good catch. - Dynamic image imports — the new
ImportExpressionAST collection mirrors the existing static-import path exactly (same.startsWith(".")vsthis.resolvelogic, same?vinext-image-url/?vinext-metacomposition, sameIMAGE_EXT_RE$-anchored gate). ReturningStaticImageDatafromimport("./foo.png")matches Next.js semantics. worker.plugins: () => [{ ...imageImportsPlugin }]— the factory is lazy, soimageImportsPluginis assigned by the time it runs; the test asserts a fresh instance per call and that user worker config (external/output/plugins) is preserved rather than replayed.- Filter regex widening to include
import(...)is safe: it only gates the handler, which is AST-based and won't rewrite non-ImportExpressionmatches (comments/strings).
Notes (non-blocking)
-
Shared-state clearing across the worker build. The cloned worker plugin (
{...imageImportsPlugin}) sharesbuildStart, which callsstaticImageAssets.clear()andimageImportDimCache.clear(). If the worker build'sbuildStartinterleaves with the client build, it could wipe entries the clientwriteBundleexpects. This is currently safe becausewriteBundlefalls back tocreateStaticImageAsset(imagePath)when the map misses, andstaticImageImportsByModuleis not cleared — but the safety relies on that fallback. Worth a one-line comment noting the intentional cache-sharing, so a future refactor ofwriteBundledoesn't remove the fallback and silently break worker/client builds. -
Dynamic-import behavior change beyond workers. The
ImportExpressionrewrite fires in all environments, soimport("./foo.png")in a regular (non-worker) client/SSR module now resolves toStaticImageDatainstead of Vite's default URL-string module. This aligns with Next.js, so it's the correct direction — just flagging that it's a broader behavioral change than the PR title ("Web Worker") implies. Consider a dedicated non-worker dynamic-import test to lock in the new contract.
Verification performed
vitest run tests/import-meta-url.test.ts tests/image-imports.test.ts— 73 passedvitest run tests/static-image-emission.test.ts -t "worker"— passedtsc --noEmit -p packages/vinext/tsconfig.json— clean
|
Review posted to PR #2892. SummaryI reviewed the 7-file diff for PR #2892, ran the relevant test suites, and type-checked the package. No blocking issues — the change is well-scoped and correct. Verified:
Non-blocking notes I raised:
Verification: 73 tests passed (import-meta-url + image-imports), worker static-image-emission passed, |
Performance benchmarksCompared 0 improved · 0 regressed · 6 within ±1.5%
View detailed results and traces 🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head |
|
/bigbonk review for issues |
There was a problem hiding this comment.
Review: fix(build): preserve Web Worker asset semantics
I read the full 7-file diff, ran the four relevant Vitest suites (import-meta-url, image-imports, static-image-emission, compatibility-support — 85 passed), type-checked and lint-checked the two source files (vp check clean), and ran vp run vinext#build (success). The change is correct and well-scoped. No blocking issues.
What's correct
isImportMetaUrlBaseNode(import-meta-url.ts:578) — precisely matches Vite's coerced worker base"" + import.meta.url(BinaryExpression, operator+, empty-stringLiteralleft,import.meta.urlchain right) and skips rewriting it, so the browser resolves emitted workers against the deployment origin instead offile:///_next/static/.... The structural match is narrow enough not to over-match. The regression test atimport-meta-url.test.ts:78locks it in (toBeNull).- Worker asset emission (
index.ts:6148) — theisWorkerbranch'sthis.emitFileis necessary because the sharedwriteBundlereturns early for any environment other thanclient(index.ts:6359), so a worker build would otherwise never write its referenced image into the worker output. The URL string returned is identical to the non-worker branch, which is intentional (both point at the deployment-origin/_next/static/media/...). - Dynamic image imports (
index.ts:6297) — the newImportExpressioncollection mirrors the static-import path exactly: same.startsWith(".")vsthis.resolveresolution, same$-anchoredIMAGE_EXT_REgate (soimport("./w.png?worker")is correctly not matched), same?vinext-image-url/?vinext-metacomposition. ReturningStaticImageDatafromimport("./x.png")matches Next.js. worker.plugins: () => [{ ...imageImportsPlugin }]— the factory is lazy so the deferredimageImportsPluginassignment is resolved by call time. I verifiedmergeConfigconcatenates the user's worker-plugins-factory result with vinext's, so user worker config (external/output/plugins) is preserved, not replayed. Theimage-imports.test.ts:24test confirms a fresh instance per call and no user-config replay.- Widened
codefilter regex (index.ts:6192) — I fuzzed it: matchesimport X from '…'andimport(…)(incl. whitespace), and does not matchimport.meta.url. Safe because the handler is AST-gated regardless.
Non-blocking observations
-
Shared cache clearing across worker/client builds. The cloned worker plugin (
{ ...imageImportsPlugin }) shares thebuildStartclosure that callsstaticImageAssets.clear()/imageImportDimCache.clear()(index.ts:6097). Safety currently relies onwriteBundle'sstaticImageAssets.get(imagePath) ?? createStaticImageAsset(imagePath)fallback (index.ts:6370) if a workerbuildStartinterleaves and wipes the map. The inline comment atindex.ts:2638documents this contract well — good. Just flagging that the fallback inwriteBundleis load-bearing for that guarantee, so a future refactor removing it would silently break worker/client parity. -
Dynamic-import rewrite fires in all environments. The
ImportExpressionrewrite runs in every environment, soimport("./foo.png")in a non-worker client/SSR module now also returnsStaticImageDatarather than Vite's default URL-string module. This is the correct Next.js direction, but it's a broader behavior change than the "Web Worker" title implies. Theimage-imports.test.ts:234unit test covers the non-worker transform/resolve/load path in isolation, which addresses the earlier suggestion for a dedicated non-worker test.
Verification performed
vp test run tests/import-meta-url.test.ts tests/image-imports.test.ts tests/static-image-emission.test.ts tests/compatibility-support.test.ts— 85 passed (incl. the workerStaticImageDataemission andfile:///_next/static/negative assertion)vp check packages/vinext/src/index.ts packages/vinext/src/plugins/import-meta-url.ts— format + lint + types cleanvp run vinext#build— success
|
Review posted to PR #2892. SummaryI reviewed the full 7-file diff, ran the four relevant Vitest suites (85 passed), lint/type-checked the two source files (clean), and built the package (success). No blocking issues — the change is correct and well-scoped. Verified correct:
Non-blocking observations raised:
|
|
Independent exact-head review of I reviewed the full seven-file diff independently, including:
Fresh validation on this immutable head:
I found no actionable asset-semantics gap, transform-ordering regression, deployment-token policy error, or missing high-value test at this head. |
|
/bigbonk review for issues |
Review SummaryI reviewed the full diff for PR #2892, verified the key behaviors against Vite's type definitions and the codebase, and ran the relevant test suites. No blocking issues — the change is correct and well-scoped. Verified correct
Non-blocking observations (already noted by prior reviews, no action required)
Verification performed
No findings. The PR honestly reports the exact upstream suite as |
|
/bigbonk review for issues |
There was a problem hiding this comment.
Review — test(worker): prove Vite-equivalent Web Worker parity
Reviewed the full diff at d1ae2e6, ran tests/import-meta-url.test.ts tests/image-imports.test.ts tests/static-image-emission.test.ts (80 passed, incl. the worker StaticImageData emission and the file:///_next/static/ negative assertion), and traced the deploy-harness runtime path.
The two source fixes are correct and I agree with the prior reviews on them:
isImportMetaUrlBaseNode(import-meta-url.ts:578) narrowly matches Vite's coerced worker base"" + import.meta.urland preserves it, so the browser resolves emitted workers against the deployment origin instead offile:///_next/static/.... The structural match won't over-match.- Worker asset emission (
index.ts:6148) is necessary becausewriteBundleearly-returns for non-clientenvironments; theloadcache makes it emit once per image id. - Dynamic image imports (
index.ts:6297) mirror the static path exactly, with a$-anchoredIMAGE_EXT_REthat correctly ignoresimport("./x.png?worker"). Theimport()namespace-object shape (pngModule.default) is what the fixture consumes — consistent withexport default { src, width, height }.
One issue: the am-i-vibing deploy-harness addition looks unnecessary
scripts/e2e-deploy.sh:581 adds am-i-vibing to every throwaway app's devDependencies, and tests/e2e-deploy-script.test.ts was updated to assert ^0.5.0. The PR description justifies this by saying vinext's runtime am-i-vibing import is "otherwise invisible while running vinext init" through the file: package.
That rationale does not hold for the harness's actual runtime path:
am-i-vibingis listed underdevDependencies(notdependencies) inpackages/vinext/package.json:192, and it isalwaysBundled into vinext'sdist(packages/vinext/vite.config.ts:77). ThisalwaysBundlepredates this PR (last touched in #2837 on 2026-08-07).- In the built output,
dist/init-platform.js:1importsisAgentvia a relative path (./deps/.pnpm/am-i-vibing@0.5.0/.../detector-*.js), anddist/cli.js:19imports./init-platform.js. There are zero barefrom "am-i-vibing"specifiers anywhere indist(verified by grep). - The harness runs the built CLI (
${VINEXT_PKG_DIR}/dist/cli.js,e2e-deploy.sh:274) and copies the fulldisttree — includingdist/deps/— into.vinext-local-package/dist(e2e-deploy.sh:481, withfiles: ['dist']at:497). The generated localpackage.jsononly carriesdependencies/peerDependencies(:499–:500), soam-i-vibing(a devDep) would never be declared there anyway.
So the isAgent import is satisfied by the inlined copy inside dist/deps/, resolved by a relative path that does not touch the app's top-level node_modules. Adding am-i-vibing to the throwaway app is a no-op for resolution.
The comment above the loop (e2e-deploy.sh:568–573) explicitly scopes it to runtime deps of vinext that pnpm doesn't hoist because they live under .vinext-local-package/node_modules and "Node's ESM resolver can't see" them from dist/.... am-i-vibing is not in that category — it's inlined, not resolved from node_modules — so it doesn't belong in this list next to genuinely-external peers like vite / react-server-dom-webpack / ipaddr.js.
This is non-blocking (the extra devDep is harmless), but it adds a misleading test assertion and a maintenance foot-gun: a future reader will assume am-i-vibing must be externally resolvable at runtime, which is not true. I'd either:
- Drop the
am-i-vibingentry (and its test assertion), or - If there is a real failing path I'm missing (e.g. a source/non-dist harness mode), keep it but correct the PR description and add a comment explaining exactly which resolution fails, since the current dist-based path does not.
If you can point me at the exact vinext init invocation that fails without it, I'll happily retract this — but from the dist I built here, the import is fully self-contained.
Non-source observations
- The Vite-equivalent Playwright spec is registered via the
cloudflare-workersproject glob (playwright.config.ts:164) and is in the CI matrix (ci.yml:520), so it will actually run. Good. - The honest
0/7accounting for the exact upstream rows (residualworker.test.ts:21:50?dplassertion only) plus the machine-audited 7/7 equivalent is the right call and matches theVITE_EQUIVALENT_LABELreclassification.
|
Review posted to PR #2892. SummaryI reviewed the full diff at The two source fixes are correct and I agree with the prior reviews:
One issue I flagged (non-blocking, and one the prior "NO FINDINGS" reviews all missed): The
So adding it to throwaway apps is a no-op for resolution and adds a misleading test assertion + maintenance foot-gun. I recommended either dropping it (and its assertion) or, if there's a real failing path I'm missing, keeping it with a corrected explanation. I also confirmed the new Playwright spec is registered via the |
|
/bigbonk review for issues |
There was a problem hiding this comment.
Review — test(worker): prove Vite-equivalent Web Worker parity
Reviewed the full diff at e86b0c0, verified the two source fixes against the codebase, built dist and traced the deploy-harness runtime resolution path, and ran the relevant Vitest suites (94 passed total). I agree with the prior reviews that the two source fixes are correct.
Source fixes — correct
isImportMetaUrlBaseNode(import-meta-url.ts:578) narrowly matches Vite's coerced worker base"" + import.meta.url(operator+, empty-stringLiteralleft,import.meta.urlchain right) and preserves it, so the browser resolves emitted workers against the deployment origin instead offile:///_next/static/.... The match won't over-match arbitrary concatenations. Locked in byimport-meta-url.test.ts(toBeNull).- Worker asset emission (
index.ts:6148) is necessary becausewriteBundleearly-returns for non-clientenvironments; the per-moduleloadcache emits once per image id. The dynamic-image path (\0vinext-dynamic-image:->?vinext-image-url) flows through this same branch, so worker emission is consistent for both static and dynamic imports. - Dynamic image imports (
index.ts:6297) mirror the static path exactly, with a$-anchoredIMAGE_EXT_REthat correctly ignoresimport("./x.png?worker"). The returned{ src, width, height }matches the static path'sStaticImageDatashape. worker.plugins: () => [{ ...imageImportsPlugin }]— the cloned plugin shares thebuildStartclosure that clearsstaticImageAssets, butwriteBundle'sstaticImageAssets.get(imagePath) ?? createStaticImageAsset(imagePath)fallback (index.ts:6370) makes that safe. The inline comment documents the contract well.
One issue: the am-i-vibing deploy-harness addition is unnecessary and its rationale is wrong
scripts/e2e-deploy.sh:581 adds am-i-vibing to every throwaway app's devDependencies, and tests/e2e-deploy-script.test.ts was updated to assert ^0.5.0. The PR description justifies this by claiming vinext's runtime am-i-vibing import is "otherwise invisible while running vinext init" through the file: package.
That rationale does not hold. I built dist and verified:
am-i-vibingis a devDependency (packages/vinext/package.json:192) and isalwaysBundled into vinext's dist (packages/vinext/vite.config.ts:77) — this predates the PR.- In the built output,
dist/init-platform.js:1importsisAgentvia a relative path (./deps/.pnpm/am-i-vibing@0.5.0/.../detector-*.js). There are zero barefrom "am-i-vibing"specifiers anywhere indist(verified by grep). - The harness runs the built CLI and
fs.cpSyncs the fulldisttree — includingdist/deps/— into.vinext-local-package/dist(e2e-deploy.sh:481,files: ['dist']at:497). The generated localpackage.jsononly carriesdependencies/peerDependencies(:499–:500), neverdevDependencies.
So the isAgent import is satisfied by the inlined copy inside dist/deps/, resolved by a relative path that never touches the app's top-level node_modules. Adding am-i-vibing to the throwaway app is a no-op for resolution.
The comment above the loop (e2e-deploy.sh:568–573) explicitly scopes it to runtime deps of vinext that pnpm doesn't hoist because "Node's ESM resolver can't see" them from dist/.... I confirmed the contrast: ipaddr.js (in the same list) IS referenced as a bare specifier in dist (dist/shims/image-config.js) and is NOT in alwaysBundle, so it genuinely needs to be resolvable in the app's node_modules. am-i-vibing is the opposite — inlined, not resolved from node_modules — so it doesn't belong in this list.
Non-blocking (the extra devDep is harmless), but it adds a misleading test assertion and a maintenance foot-gun: a future reader will assume am-i-vibing must be externally resolvable at runtime, which is false. I'd either:
- Drop the
am-i-vibingentry (and its test assertion), or - If there's a real failing
vinext initpath I'm missing, keep it but correct the PR description and add a comment explaining exactly which resolution fails — the current dist-based path is fully self-contained.
This has now been flagged in multiple reviews without being addressed. If you can point me at the exact invocation that fails without it, I'll retract; otherwise it should be dropped.
Non-source observations (no action)
- The honest
0/7accounting for the exact upstream rows (residualworker.test.ts:21:50?dplassertion only) plus the machine-audited 7/7 Vite-equivalent is the right call. The provenance manifest correctly separatesbyteExactFixturePaths(upstream, hash-pinned) from the local equivalent files (package.json,vite.config.mjs,wrangler.jsonc) — no dishonest "byte-for-byte" overclaim. - The Vite-equivalent Playwright spec is registered via the
cloudflare-workersproject glob (playwright.config.ts:164) and is in the CI matrix (ci.yml:520), so it will actually run. - The
knip.ts/vite.config.tsexclusions for the pinned fixture are appropriate.
Verification performed
vitest run tests/import-meta-url.test.ts tests/image-imports.test.ts tests/static-image-emission.test.ts— 80 passed (incl. workerStaticImageDataemission +file:///_next/static/negative assertion)vitest run tests/e2e-deploy-script.test.ts tests/worker-e2e-provenance.test.ts tests/compatibility-support.test.ts— 14 passed- Built dist inspection confirming the
am-i-vibingrelative-import / zero-bare-specifier finding
|
Review posted to PR #2892. SummaryI reviewed the full diff at Source fixes — correct (I agree with prior reviews):
One issue confirmed (non-blocking, previously flagged, still unaddressed): The
Recommended dropping the entry + its test assertion, or correcting the rationale if there's a real failing path. The honest |
|
/bigbonk review for issues |
|
UnknownError: ProviderInitError |
|
@james-elicx Bonk workflow failed. Check the logs for details. View workflow run · To retry, trigger Bonk again. |
|
/bigbonk review for issues |
There was a problem hiding this comment.
Review — test(worker): prove Vite-equivalent Web Worker parity
Reviewed the full diff at 45e60d9, ran the relevant Vitest suites (94 passed), lint/type-checked the two source files (clean), and traced the fixture/provenance wiring. No blocking issues — and the one recurring non-blocking finding from prior rounds has now been fixed.
am-i-vibing finding is resolved
The last commit (45e60d9, "drop redundant harness dependency") removes am-i-vibing from the scripts/e2e-deploy.sh throwaway-app dependency loop and deletes the corresponding ^0.5.0 assertion in tests/e2e-deploy-script.test.ts. This is the correct resolution of the finding flagged across the previous reviews (the dep is alwaysBundled into dist and imported via a relative ./deps/ path, so it was never externally resolvable and the entry was a no-op + misleading assertion). Nothing else references it. Good.
Source fixes — correct
isImportMetaUrlBaseNode(import-meta-url.ts:578) narrowly matches Vite's coerced worker base"" + import.meta.url(BinaryExpression, operator+, empty-stringLiteralleft,import.meta.url/optional-chained right) and preserves it, so the browser resolves emitted workers against the deployment origin instead offile:///_next/static/.... The match won't over-match arbitrary concatenations.- Worker asset emission (
index.ts:6148) — theisWorkeremitFilebranch is necessary becausewriteBundleearly-returns for any non-clientenvironment (index.ts:6359), so a worker build would otherwise never write its referenced image.loadis cached per module id, so the emit happens once per image. - Dynamic image imports (
index.ts:6294) mirror the static path: same.startsWith(".")vsthis.resolveresolution, same$-anchoredIMAGE_EXT_REgate (soimport("./x.png?worker")is correctly not matched), sameimageImports.add()registration forwriteBundle. The\0vinext-dynamic-image:module re-emits?vinext-image-url+?vinext-metaand returns{ src, width, height }— the exact shapepng-worker.tsconsumes viapngModule.default({ src, width, height }). Consistent with the static path and with the fixture. worker.plugins: () => [{ ...imageImportsPlugin }]— the lazy factory resolves the deferredimageImportsPluginassignment by call time; the cloned plugin shares thebuildStartcache-clearing closure, made safe bywriteBundle'sstaticImageAssets.get(...) ?? createStaticImageAsset(...)fallback (documented inline atindex.ts:2638).- Widened
codefilter regex (index.ts:6192) now also matchesimport(...); safe because the handler is AST-gated.
Honesty / provenance — sound
tests/worker-e2e-provenance.test.tsmachine-audits the equivalence: it hashes the pinned upstream snapshot, structurally compares all seven ordereditbodies (routes + normalized AST) after removing exactly the sevenbeforePageLoad(?dpl) hook uses, assertsomissions === 7andremovednames only that hook, and hashes all 17 byte-exact upstream fixture assets plus every checked-in fixture file. This is a genuine audit, not a rubber stamp.- The compat policy reclassification (
suite-support.ts→VITE_EQUIVALENT_LABEL"Vite-equivalent required") honestly leaves the exact upstream rows at0/7and does not claim a Next.js pass. ThebyteExactFixturePathsmanifest correctly separates hash-pinned upstream fixtures (app/,public/) from local equivalents (package.json,vite.config.mjs,wrangler.jsonc). worker.spec.tsis registered via thecloudflare-workersproject glob (playwright.config.ts:164) and is in the CI matrix (ci.yml:520), so it actually runs. Theknip.ts/vite.config.tsfixture exclusions are appropriate.
Minor observations (non-blocking, no action required)
- The dynamic-import rewrite fires in all environments, so
import("./foo.png")in non-worker modules also returnsStaticImageDatanow. This is correct per Next.js but broader than the "Web Worker" title implies;image-imports.test.tscovers the non-worker path. worker.spec.ts'sbeforeAllsymlinksexamples/app-router-cloudflare/node_modulesfor the fixture (which has an emptypackage.json) and spawns its own build+wrangler on port 4201, in addition to the project's own server on 4176. It's a heavier-than-usual setup but self-contained and correct; just noting the two-build cost.
Verification performed
vp test run tests/import-meta-url.test.ts tests/image-imports.test.ts tests/static-image-emission.test.ts— 80 passed (incl. workerStaticImageDataemission +file:///_next/static/negative assertion)vp test run tests/e2e-deploy-script.test.ts tests/worker-e2e-provenance.test.ts tests/compatibility-support.test.ts— 14 passedvp check packages/vinext/src/index.ts packages/vinext/src/plugins/import-meta-url.ts— format + lint + types clean- Head SHA
45e60d9matches local checkout
No findings.
|
Review posted to PR #2892. SummaryI reviewed the full diff at head The one recurring finding is now fixed. The latest commit Verified correct:
Provenance/honesty is sound: the machine audit structurally compares all 7 test bodies + routes after removing exactly the 7 Two minor non-blocking observations noted (dynamic-import rewrite fires in all environments; the spec's symlink+two-build setup is heavy but self-contained). No findings requiring changes. |
|
/bigbonk review for issues |
|
UnknownError: ProviderInitError |
|
/bigbonk review for issues |
1 similar comment
|
/bigbonk review for issues |
There was a problem hiding this comment.
Review — test(worker): prove Vite-equivalent Web Worker parity
Reviewed the full diff at head 45e60d9. I re-verified both source fixes against the codebase, exercised the dynamic-image traversal path, and ran the relevant Vitest suites (all green). No blocking issues. The two source fixes are correct, and the honesty/provenance framing is sound. I have one small accuracy nit that prior rounds missed.
Source fixes — correct
isImportMetaUrlBaseNode(import-meta-url.ts:578) narrowly matches Vite's coerced worker base"" + import.meta.url(BinaryExpression, operator+, empty-stringLiteralleft,import.meta.url/optional-chained right) and preserves it, so emitted workers resolve against the deployment origin instead offile:///_next/static/.... The structural match won't over-match arbitrary concatenations; locked in byimport-meta-url.test.ts(toBeNull).- Worker asset emission (
index.ts:6148) — theisWorkeremitFilebranch is necessary becausewriteBundleearly-returns for any non-clientenvironment (index.ts:6359).loadis cached per module id, so the emit happens once per image. Both branches callrenderVinextBuiltUrl(...)identically, so thedeploymentId/assetPrefixURL shape stays consistent across worker and non-worker builds. - Dynamic image imports (
index.ts:6294) —collectDynamicImageImportsdoes a full recursive AST walk viaforEachAstChild(metadata-onlySKIP_CHILD_KEYS), so it findsimport()nested inside functions (as inpng-worker.ts). The$-anchoredIMAGE_EXT_REcorrectly ignoresimport("./x.png?worker"), and onlyLiteralstring sources are rewritten (template-literalimport()is left alone, matching what any static analyzer can do). The\0vinext-dynamic-image:module re-imports?vinext-image-url+?vinext-metaand returns{ src, width, height }— the exact shapepng-worker.tsconsumes viapngModule.default. worker.plugins: () => [{ ...imageImportsPlugin }]— the lazy factory resolves the deferred assignment by call time; the cloned plugin shares thebuildStartcache-clearing closure, made safe bywriteBundle'sstaticImageAssets.get(...) ?? createStaticImageAsset(...)fallback. Documented inline. Good.
Honesty / provenance — sound
worker-e2e-provenance.test.ts is a genuine machine audit, not a rubber stamp: it hashes the pinned upstream snapshot, structurally compares all seven ordered it bodies (routes + metadata-stripped AST) after removing exactly the seven beforePageLoad (?dpl) hook uses, asserts omissions === 7, and hashes every fixture file. The compat reclassification (suite-support.ts → VITE_EQUIVALENT_LABEL) honestly keeps the exact upstream rows at 0/7 rather than claiming a Next.js pass. Correct call.
Nit (non-blocking, not raised in prior rounds)
The knip.ts and vite.config.ts exclusion comments claim the entire worker-fixture/** glob is "Pinned byte-for-byte from Next.js v16.2.6":
// Pinned byte-for-byte from Next.js v16.2.6; provenance tests verify hashes.
"tests/e2e/cloudflare-workers/worker-fixture/**",
That is only true for app/ and public/. The provenance test itself proves the distinction (worker-e2e-provenance.test.ts:244-246 asserts byteExactFixturePaths == only files under app//public/), and the manifest lists package.json, vite.config.mjs, and wrangler.jsonc as equivalentLocalFiles — these are vinext-authored (e.g. vite.config.mjs imports vinext + @cloudflare/vite-plugin), not upstream bytes. The glob exclusion behavior is correct regardless of origin; only the justifying comment overclaims. Worth softening to e.g. "Pinned upstream fixture (app//public/ byte-exact) plus vinext-local build config" so a future reader doesn't assume those three files are immutable upstream copies.
Verification performed
vitest run tests/import-meta-url.test.ts tests/image-imports.test.ts— 74 passed (incl. fresh-per-call worker plugin + dynamicStaticImageData)vitest run tests/static-image-emission.test.ts -t "worker"— passed (real Vite worker build emits the image; asserts nofile:///_next/static/)vitest run tests/worker-e2e-provenance.test.ts tests/compatibility-support.test.ts— 7 passedvp check packages/vinext/src/index.ts packages/vinext/src/plugins/import-meta-url.ts— format + lint + types clean
No findings requiring changes.
|
Review posted to PR #2892. SummaryReviewed the full diff at head Source fixes — correct:
Provenance/honesty — sound: the machine audit genuinely compares all 7 test bodies after removing exactly the 7 One accuracy nit (non-blocking, missed by prior rounds): The The recurring |
Summary
Proves portable Web Worker parity for the failures seen in Actions run 31439707085 without misreporting the upstream Next.js suite as passing.
The implementation fix preserves Vite's emitted Worker URL base instead of rewriting it to a source-file URL, registers a fresh image-import plugin for Worker builds, and gives dynamic image imports the Next-compatible
StaticImageDatashape. The checked-in equivalent now exercises classic Workers, module Workers, literal-string Workers,NEXT_DEPLOYMENT_ID, WASM, SharedWorkers, and PNG imports in a real Vite/Rolldown + Wrangler/Workerd browser path.The deploy harness also hoists
am-i-vibinginto throwaway apps.vinextis materialized through afile:package there, so its runtime import is otherwise invisible while runningvinext init.Honest result accounting
?dplfailure messages. Every residual failure is exclusivelyworker.test.ts:21:50.The exact rows therefore remain visible as
0/7and are classified Vite-equivalent required. This PR does not claim that seven exact Next.js rows pass.Provenance
tests/e2e/cloudflare-workers/worker.spec.tstests/e2e/cloudflare-workers/worker-fixture/tests/e2e/cloudflare-workers/provenance/worker.test.v16.2.6.txttests/e2e/cloudflare-workers/provenance/worker-fixture.v16.2.6.jsontests/worker-e2e-provenance.test.tsThe machine audit verifies all seven ordered test bodies and routes after removing exactly the seven uses of the single suite-wide
beforePageLoadhook. It also verifies the pinned suite/config snapshots, all 17 byte-exact upstream fixture assets, and every checked-in local fixture file. The only omitted behavior is Turbopack's global?dpl=assertion on every/_next/request.Validation
worker.test.ts:21:50, portable passing assertions 2/2/2/3/2/2/8vp run vinext#build: passedvp run @vinext/cloudflare#build: passedvp check: passed