@@ -205,6 +205,7 @@ await patchBrowserProviderLocators();
205205
206206// Step 9: Post-processing
207207await patchVendorPaths ( ) ;
208+ await patchVitestCoreResolver ( ) ;
208209await createBrowserCompatShim ( ) ;
209210await createModuleRunnerStub ( ) ;
210211await createNodeEntry ( ) ;
@@ -1077,6 +1078,68 @@ async function patchVendorPaths() {
10771078 }
10781079}
10791080
1081+ /**
1082+ * Patch VitestCoreResolver to resolve @voidzero-dev/vite-plus/test directly.
1083+ *
1084+ * Problem: CLI's `export * from '@voidzero-dev/vite-plus-test'` creates a re-export
1085+ * chain that breaks module identity in Vite's SSR transform. expect.extend()
1086+ * mutations aren't visible through the re-export.
1087+ *
1088+ * Fix: Make VitestCoreResolver resolve both @voidzero-dev/vite-plus/test and
1089+ * @voidzero -dev/vite-plus-test directly to dist/index.js, bypassing re-exports.
1090+ */
1091+ async function patchVitestCoreResolver ( ) {
1092+ console . log ( '\nPatching VitestCoreResolver for CLI package alias...' ) ;
1093+
1094+ const cliApiChunks = await fsGlob ( join ( distDir , 'chunks/cli-api.*.js' ) ) ;
1095+ const cliApiChunkArr : string [ ] = [ ] ;
1096+ for await ( const chunk of cliApiChunks ) {
1097+ cliApiChunkArr . push ( chunk ) ;
1098+ }
1099+
1100+ if ( cliApiChunkArr . length === 0 ) {
1101+ throw new Error ( 'cli-api chunk not found' ) ;
1102+ }
1103+
1104+ const cliApiChunk = cliApiChunkArr [ 0 ] ;
1105+ let content = await readFile ( cliApiChunk , 'utf8' ) ;
1106+
1107+ // Find the VitestCoreResolver resolveId function and add our package aliases
1108+ const oldPattern = `async resolveId(id) {
1109+ if (id === "vitest") return resolve(distDir, "index.js");
1110+ if (id.startsWith("@vitest/") || id.startsWith("vitest/"))` ;
1111+
1112+ const newCode = `async resolveId(id) {
1113+ if (id === "vitest") return resolve(distDir, "index.js");
1114+ // Resolve CLI test path and test package directly to dist/index.js
1115+ // This bypasses the re-export chain and ensures module identity is preserved
1116+ if (id === "@voidzero-dev/vite-plus/test" || id === "@voidzero-dev/vite-plus-test") {
1117+ return resolve(distDir, "index.js");
1118+ }
1119+ // Handle subpaths: @voidzero-dev/vite-plus/test/* -> vitest/*
1120+ if (id.startsWith("@voidzero-dev/vite-plus/test/")) {
1121+ const subpath = id.slice("@voidzero-dev/vite-plus/test/".length);
1122+ return this.resolve("vitest/" + subpath, join(ctx.config.root, "index.html"), { skipSelf: true });
1123+ }
1124+ // Handle subpaths: @voidzero-dev/vite-plus-test/* -> vitest/*
1125+ if (id.startsWith("@voidzero-dev/vite-plus-test/")) {
1126+ const subpath = id.slice("@voidzero-dev/vite-plus-test/".length);
1127+ return this.resolve("vitest/" + subpath, join(ctx.config.root, "index.html"), { skipSelf: true });
1128+ }
1129+ if (id.startsWith("@vitest/") || id.startsWith("vitest/"))` ;
1130+
1131+ if ( ! content . includes ( oldPattern ) ) {
1132+ throw new Error (
1133+ 'Could not find VitestCoreResolver pattern to patch. ' +
1134+ 'This likely means vitest code has changed and the patch needs to be updated.' ,
1135+ ) ;
1136+ }
1137+
1138+ content = content . replace ( oldPattern , newCode ) ;
1139+ await writeFile ( cliApiChunk , content ) ;
1140+ console . log ( ' Patched VitestCoreResolver to resolve @voidzero-dev/vite-plus/test directly' ) ;
1141+ }
1142+
10801143/**
10811144 * Convert tabs to spaces in all JS files in dist/ for consistent formatting.
10821145 * This allows our patching code to use space-based patterns instead of tabs.
0 commit comments