refactor: migrate ssrLoadModule to moduleRunner.import - #570
Conversation
Replace all server.ssrLoadModule() calls in dev-server.ts and api-handler.ts with runner.import() via the ModuleImporter interface, following the Vite Module Runner migration guide. Remove ssrFixStacktrace calls which are not needed with Module Runner APIs. Update call sites in index.ts to pass the existing getPagesRunner() lazy factory as the runner argument. Update tests to use ModuleImporter-shaped mocks instead of the old ViteDevServer mock.
commit: |
|
|
/bigbonk review |
There was a problem hiding this comment.
Review: Migrate ssrLoadModule to ModuleRunner
Clean, well-scoped refactor. The migration from server.ssrLoadModule() to runner.import() via the ModuleImporter interface is correct and consistent. All CI checks pass.
What's good
- Complete migration: All 18
ssrLoadModulecalls indev-server.tsand the call inapi-handler.tsare replaced. No stale references remain (only comments explaining the old pattern). - Interface reuse:
ModuleImporterwas already defined ininstrumentation.tsand used byrunInstrumentationandrunMiddleware. This PR extends its use to the remaining call sites — consistent with the existing pattern. serverparam retained where needed:createSSRHandlerandrenderErrorPagestill acceptViteDevServerbecause they needserver.transformIndexHtml(). Therunneris additive, not a replacement forserverin those signatures.- Test updates are correct: The
api-handler.test.tsmock is now a cleanModuleImportershape (no moreas unknown as MockServercast). Thepages-router.test.tsmock extractsloadModuleas a shared function used by bothserver.ssrLoadModule(still needed for theViteDevServercast) andrunner.import.
Minor observations (non-blocking)
-
sourcemapInterceptor: falseincreateDirectRunner— The PR description says "ssrFixStacktrace/ssrRewriteStacktrace are not needed when using Module Runner APIs." This is technically accurate forssrFixStacktracespecifically (it only applies tossrLoadModule-loaded modules), but the direct runner hassourcemapInterceptor: false, which means the Module Runner is not doing automatic source map rewriting either. In dev, Node's--enable-source-mapsor Vite's dev server error overlay handles this, so it's fine in practice. But the comments "Stack traces are automatically rewritten by the ModuleRunner" atdev-server.ts:1001andapi-handler.ts:245are slightly misleading — the runner created bycreateDirectRunnerhas source map interception disabled. Consider updating the comments to say something like "ssrFixStacktrace is specific to ssrLoadModule and is not applicable when using ModuleRunner" instead. -
ALS-ARCHITECTURE.mdstill referencesssrLoadModule— Lines 81 and 95 still sayserver.ssrLoadModule("vinext/head-state"). These are architectural docs, not code, so it's low priority, but worth a follow-up update for accuracy. -
eslint-disablecomments — There are ~12 neweslint-disable-next-line @typescript-eslint/no-explicit-anycomments for theas Record<string, any>casts onrunner.import(). This is a consequence ofModuleImporter.import()returningPromise<unknown>. An alternative would be a typed helper likeasync function importModule(runner: ModuleImporter, id: string): Promise<Record<string, any>>to centralize the cast and eliminate the inline disables. Not blocking, but would reduce noise. -
Stale mock in
pages-router.test.ts— The test at line 2957 still setsssrLoadModule: vi.fn(loadModule)on the mock server object. SincecreateSSRHandlerno longer callsserver.ssrLoadModule, this mock property is dead code. Removing it would make the test clearer about what's actually exercised.
Looks good overall.
|
Review posted and approved on PR #570. Here's a summary: Approved — This is a clean, well-scoped refactor that correctly migrates all I raised 4 non-blocking observations:
|
- Fix misleading stack trace comments: ssrFixStacktrace is not applicable to ModuleRunner (not that it rewrites automatically) - Update ALS-ARCHITECTURE.md to reference runner.import() instead of server.ssrLoadModule() - Add importModule() typed helper to instrumentation.ts to centralise the Record<string, any> cast, removing 12 inline eslint-disable comments - Remove dead ssrLoadModule mock from pages-router ISR test (createSSRHandler no longer calls server.ssrLoadModule)
|
/bigbonk re-review |
There was a problem hiding this comment.
Review: Migrate ssrLoadModule to ModuleRunner
This is a clean, complete migration. All 18 ssrLoadModule calls in dev-server.ts and the call in api-handler.ts are replaced with runner.import() via the existing ModuleImporter interface. No functional call sites were missed.
What's correct
-
Complete coverage: Every
ssrLoadModulecall indev-server.tsandapi-handler.tsis migrated. The remainingssrLoadModulereference attests/pages-router.test.ts:999is in the "Virtual server entry generation" test, which tests loading the virtual module itself (not the SSR handler path) — correctly untouched. -
importModulehelper: The newimportModule()function ininstrumentation.ts:58-63centralises theas Record<string, any>cast, which directly addresses ask-bonk's observation #3 about eslint-disable noise. The remaining inlinerunner.import()calls at lines 259-260 (vinext/head-state,vinext/router-state), line 363, line 613, and the_app/_documentloads are for registration-only or structural loads where the return value only needs.default— using the rawrunner.import()with a one-off cast is fine there. -
serverparam retained correctly:createSSRHandlerandrenderErrorPagestill acceptViteDevServerbecause they callserver.transformIndexHtml()and readserver.config.root. Therunneris purely additive. -
No prod-server/worker-entry changes needed: I verified
prod-server.tsandworker-entry.ts— they don't usessrLoadModule(production uses bundled imports, not runtime module loading). The AGENTS.md parity check passes. -
ALS-ARCHITECTURE.md updated: Lines 81 and 95 now correctly reference
runner.import()and theModuleImporterinterface instead ofserver.ssrLoadModule(). This addresses ask-bonk's observation #2.
One minor observation
The comments at dev-server.ts:990 and api-handler.ts:244 say "ssrFixStacktrace() is specific to ssrLoadModule and is not applicable when using ModuleRunner." This is accurate and better than what ask-bonk suggested the original comments said. The current wording correctly explains why the call was removed without making any claim about automatic rewriting. Good.
LGTM — approve.
|
Review posted and approved on PR #570. Here's a summary of my findings: Approved — this is a clean, complete migration of all Key points from my review:
|
Summary
server.ssrLoadModule()calls indev-server.tsandapi-handler.tswithrunner.import()via theModuleImporterinterface, following the Vite Module Runner migration guidessrFixStacktrace/ssrRewriteStacktracecalls — these are not needed when using Module Runner APIsindex.tsto pass the existinggetPagesRunner()lazy factory as the newrunnerargumentFiles changed
packages/vinext/src/server/dev-server.tsssrLoadModulecalls →runner.import(),ssrFixStacktraceremoved,runner: ModuleImporteradded tocreateSSRHandlerandrenderErrorPagesignaturespackages/vinext/src/server/api-handler.tsserver: ViteDevServer→runner: ModuleImporter,ssrLoadModule→runner.import(),ssrFixStacktraceremovedpackages/vinext/src/index.tsgetPagesRunner()as the runnertests/api-handler.test.tsMockServertype +mockServer()helper replaced withModuleImporter-shaped mock; removed stalessrFixStacktraceassertiontests/pages-router.test.tscreateSSRHandlercall updated to pass arunnerderived from the existing mock logicTesting
api-handlerunit tests passpnpm run checkis clean (2 pre-existing benchmark errors unrelated to this change)