Skip to content

Commit 151c25c

Browse files
authored
refactor vite plugin (#12539)
* namespace vite plugins with `react-router:` * refactor: pre-compute virtual module resolvedId and url
1 parent a897f99 commit 151c25c

File tree

4 files changed

+60
-54
lines changed

4 files changed

+60
-54
lines changed

packages/react-router-dev/vite/plugin.ts

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { generate, parse } from "./babel";
3131
import type { NodeRequestHandler } from "./node-adapter";
3232
import { fromNodeRequest, toNodeRequest } from "./node-adapter";
3333
import { getStylesForUrl, isCssModulesFile } from "./styles";
34-
import * as VirtualModule from "./vmod";
34+
import * as VirtualModule from "./virtual-module";
3535
import { resolveFileUrl } from "./resolve-file-url";
3636
import { combineURLs } from "./combine-urls";
3737
import { removeExports } from "./remove-exports";
@@ -163,11 +163,8 @@ export type ReactRouterPluginContext = ReactRouterPluginSsrBuildContext & {
163163
viteManifestEnabled: boolean;
164164
};
165165

166-
let serverBuildId = VirtualModule.id("server-build");
167-
let serverManifestId = VirtualModule.id("server-manifest");
168-
let browserManifestId = VirtualModule.id("browser-manifest");
169-
let hmrRuntimeId = VirtualModule.id("hmr-runtime");
170-
let injectHmrRuntimeId = VirtualModule.id("inject-hmr-runtime");
166+
let virtualHmrRuntime = VirtualModule.create("hmr-runtime");
167+
let virtualInjectHmrRuntime = VirtualModule.create("inject-hmr-runtime");
171168

172169
const resolveRelativeRouteFilePath = (
173170
route: RouteManifestEntry,
@@ -180,13 +177,15 @@ const resolveRelativeRouteFilePath = (
180177
return vite.normalizePath(fullPath);
181178
};
182179

183-
let vmods = [serverBuildId, serverManifestId, browserManifestId];
180+
let virtual = {
181+
serverBuild: VirtualModule.create("server-build"),
182+
serverManifest: VirtualModule.create("server-manifest"),
183+
browserManifest: VirtualModule.create("browser-manifest"),
184+
};
184185

185-
const invalidateVirtualModules = (viteDevServer: Vite.ViteDevServer) => {
186-
vmods.forEach((vmod) => {
187-
let mod = viteDevServer.moduleGraph.getModuleById(
188-
VirtualModule.resolve(vmod)
189-
);
186+
let invalidateVirtualModules = (viteDevServer: Vite.ViteDevServer) => {
187+
Object.values(virtual).forEach((vmod) => {
188+
let mod = viteDevServer.moduleGraph.getModuleById(vmod.resolvedId);
190189
if (mod) {
191190
viteDevServer.moduleGraph.invalidateModule(mod);
192191
}
@@ -513,7 +512,9 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
513512
)};`;
514513
})
515514
.join("\n")}
516-
export { default as assets } from ${JSON.stringify(serverManifestId)};
515+
export { default as assets } from ${JSON.stringify(
516+
virtual.serverManifest.id
517+
)};
517518
export const assetsBuildDirectory = ${JSON.stringify(
518519
path.relative(
519520
ctx.rootDirectory,
@@ -709,12 +710,9 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
709710

710711
return {
711712
version: String(Math.random()),
712-
url: combineURLs(ctx.publicPath, VirtualModule.url(browserManifestId)),
713+
url: combineURLs(ctx.publicPath, virtual.browserManifest.url),
713714
hmr: {
714-
runtime: combineURLs(
715-
ctx.publicPath,
716-
VirtualModule.url(injectHmrRuntimeId)
717-
),
715+
runtime: combineURLs(ctx.publicPath, virtualInjectHmrRuntime.url),
718716
},
719717
entry: {
720718
module: combineURLs(
@@ -908,7 +906,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
908906
preserveEntrySignatures: "exports-only",
909907
input:
910908
viteUserConfig.build?.rollupOptions?.input ??
911-
serverBuildId,
909+
virtual.serverBuild.id,
912910
output: {
913911
entryFileNames:
914912
ctx.reactRouterConfig.serverBuildFile,
@@ -1012,8 +1010,8 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
10121010
plugin !== null &&
10131011
"name" in plugin &&
10141012
plugin.name !== "react-router" &&
1015-
plugin.name !== "react-router-route-exports" &&
1016-
plugin.name !== "react-router-hmr-updates"
1013+
plugin.name !== "react-router:route-exports" &&
1014+
plugin.name !== "react-router:hmr-updates"
10171015
),
10181016
],
10191017
});
@@ -1119,7 +1117,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
11191117
viteDevServer.middlewares.use(async (req, res, next) => {
11201118
try {
11211119
let build = (await viteDevServer.ssrLoadModule(
1122-
serverBuildId
1120+
virtual.serverBuild.id
11231121
)) as ServerBuild;
11241122

11251123
let handler = createRequestHandler(build, "development");
@@ -1253,7 +1251,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
12531251
},
12541252
},
12551253
{
1256-
name: "react-router-route-entry",
1254+
name: "react-router:route-entry",
12571255
enforce: "pre",
12581256
async transform(_code, id, options) {
12591257
if (!isRouteEntry(id)) return;
@@ -1279,17 +1277,18 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
12791277
},
12801278
},
12811279
{
1282-
name: "react-router-virtual-modules",
1280+
name: "react-router:virtual-modules",
12831281
enforce: "pre",
12841282
resolveId(id) {
1285-
if (vmods.includes(id)) return VirtualModule.resolve(id);
1283+
const vmod = Object.values(virtual).find((vmod) => vmod.id === id);
1284+
if (vmod) return vmod.resolvedId;
12861285
},
12871286
async load(id) {
12881287
switch (id) {
1289-
case VirtualModule.resolve(serverBuildId): {
1288+
case virtual.serverBuild.resolvedId: {
12901289
return await getServerEntry();
12911290
}
1292-
case VirtualModule.resolve(serverManifestId): {
1291+
case virtual.serverManifest.resolvedId: {
12931292
let reactRouterManifest = ctx.isSsrBuild
12941293
? await ctx.getReactRouterServerManifest()
12951294
: await getReactRouterManifestForDev();
@@ -1298,7 +1297,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
12981297
es6: true,
12991298
})};`;
13001299
}
1301-
case VirtualModule.resolve(browserManifestId): {
1300+
case virtual.browserManifest.resolvedId: {
13021301
if (viteCommand === "build") {
13031302
throw new Error("This module only exists in development");
13041303
}
@@ -1314,7 +1313,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
13141313
},
13151314
},
13161315
{
1317-
name: "react-router-dot-server",
1316+
name: "react-router:dot-server",
13181317
enforce: "pre",
13191318
async resolveId(id, importer, options) {
13201319
// https://vitejs.dev/config/dep-optimization-options
@@ -1324,9 +1323,9 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
13241323

13251324
if (isOptimizeDeps || options?.ssr) return;
13261325

1327-
let isResolving = options?.custom?.["react-router-dot-server"] ?? false;
1326+
let isResolving = options?.custom?.["react-router:dot-server"] ?? false;
13281327
if (isResolving) return;
1329-
options.custom = { ...options.custom, "react-router-dot-server": true };
1328+
options.custom = { ...options.custom, "react-router:dot-server": true };
13301329
let resolved = await this.resolve(id, importer, options);
13311330
if (!resolved) return;
13321331

@@ -1384,7 +1383,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
13841383
},
13851384
},
13861385
{
1387-
name: "react-router-dot-client",
1386+
name: "react-router:dot-client",
13881387
async transform(code, id, options) {
13891388
if (!options?.ssr) return;
13901389
let clientFileRE = /\.client(\.[cm]?[jt]sx?)?$/;
@@ -1406,7 +1405,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
14061405
},
14071406
WithProps.plugin,
14081407
{
1409-
name: "react-router-route-exports",
1408+
name: "react-router:route-exports",
14101409
async transform(code, id, options) {
14111410
let route = getRoute(ctx.reactRouterConfig, id);
14121411
if (!route) return;
@@ -1454,17 +1453,18 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
14541453
},
14551454
},
14561455
{
1457-
name: "react-router-inject-hmr-runtime",
1456+
name: "react-router:inject-hmr-runtime",
14581457
enforce: "pre",
14591458
resolveId(id) {
1460-
if (id === injectHmrRuntimeId)
1461-
return VirtualModule.resolve(injectHmrRuntimeId);
1459+
if (id === virtualInjectHmrRuntime.id) {
1460+
return virtualInjectHmrRuntime.resolvedId;
1461+
}
14621462
},
14631463
async load(id) {
1464-
if (id !== VirtualModule.resolve(injectHmrRuntimeId)) return;
1464+
if (id !== virtualInjectHmrRuntime.resolvedId) return;
14651465

14661466
return [
1467-
`import RefreshRuntime from "${hmrRuntimeId}"`,
1467+
`import RefreshRuntime from "${virtualHmrRuntime.id}"`,
14681468
"RefreshRuntime.injectIntoGlobalHook(window)",
14691469
"window.$RefreshReg$ = () => {}",
14701470
"window.$RefreshSig$ = () => (type) => type",
@@ -1473,13 +1473,13 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
14731473
},
14741474
},
14751475
{
1476-
name: "react-router-hmr-runtime",
1476+
name: "react-router:hmr-runtime",
14771477
enforce: "pre",
14781478
resolveId(id) {
1479-
if (id === hmrRuntimeId) return VirtualModule.resolve(hmrRuntimeId);
1479+
if (id === virtualHmrRuntime.id) return virtualHmrRuntime.resolvedId;
14801480
},
14811481
async load(id) {
1482-
if (id !== VirtualModule.resolve(hmrRuntimeId)) return;
1482+
if (id !== virtualHmrRuntime.resolvedId) return;
14831483

14841484
let reactRefreshDir = path.dirname(
14851485
require.resolve("react-refresh/package.json")
@@ -1501,7 +1501,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
15011501
},
15021502
},
15031503
{
1504-
name: "react-router-react-refresh-babel",
1504+
name: "react-router:react-refresh-babel",
15051505
async transform(code, id, options) {
15061506
if (viteCommand !== "serve") return;
15071507
if (id.includes("/node_modules/")) return;
@@ -1543,7 +1543,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
15431543
},
15441544
},
15451545
{
1546-
name: "react-router-hmr-updates",
1546+
name: "react-router:hmr-updates",
15471547
async handleHotUpdate({ server, file, modules, read }) {
15481548
let route = getRoute(ctx.reactRouterConfig, file);
15491549

@@ -1553,8 +1553,9 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
15531553

15541554
if (route) {
15551555
// invalidate manifest on route exports change
1556-
let serverManifest = (await server.ssrLoadModule(serverManifestId))
1557-
.default as ReactRouterManifest;
1556+
let serverManifest = (
1557+
await server.ssrLoadModule(virtual.serverManifest.id)
1558+
).default as ReactRouterManifest;
15581559

15591560
let oldRouteMetadata = serverManifest.routes[route.id];
15601561
let newRouteMetadata = await getRouteMetadata(
@@ -1653,7 +1654,7 @@ function withCommentBoundaries(label: string, text: string) {
16531654
}
16541655

16551656
const REACT_REFRESH_HEADER = `
1656-
import RefreshRuntime from "${hmrRuntimeId}";
1657+
import RefreshRuntime from "${virtualHmrRuntime.id}";
16571658
16581659
const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
16591660
let prevRefreshReg;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export function create(name: string) {
2+
let id = `virtual:react-router/${name}`;
3+
return {
4+
id,
5+
resolvedId: `\0${id}`,
6+
url: `/@id/__x00__${id}`,
7+
};
8+
}

packages/react-router-dev/vite/vmod.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

packages/react-router-dev/vite/with-props.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ import dedent from "dedent";
33

44
import type { Babel, NodePath, ParseResult } from "./babel";
55
import { traverse, t } from "./babel";
6-
import * as VirtualModule from "./vmod";
6+
import * as VirtualModule from "./virtual-module";
77

8-
const vmodId = VirtualModule.id("with-props");
8+
const vmod = VirtualModule.create("with-props");
99

1010
const NAMED_COMPONENT_EXPORTS = ["HydrateFallback", "ErrorBoundary"];
1111

1212
export const plugin: Plugin = {
1313
name: "react-router-with-props",
1414
enforce: "pre",
1515
resolveId(id) {
16-
if (id === vmodId) return VirtualModule.resolve(vmodId);
16+
if (id === vmod.id) return vmod.resolvedId;
1717
},
1818
async load(id) {
19-
if (id !== VirtualModule.resolve(vmodId)) return;
19+
if (id !== vmod.resolvedId) return;
2020
return dedent`
2121
import { createElement as h } from "react";
2222
import { useActionData, useLoaderData, useMatches, useParams, useRouteError } from "react-router";
@@ -126,7 +126,7 @@ export const transform = (ast: ParseResult<Babel.File>) => {
126126
hocs.map(([name, identifier]) =>
127127
t.importSpecifier(identifier, t.identifier(name))
128128
),
129-
t.stringLiteral(vmodId)
129+
t.stringLiteral(vmod.id)
130130
)
131131
);
132132
}

0 commit comments

Comments
 (0)