@react-router/dev 0.0.0-experimental-e1f760554 → 0.0.0-experimental-a839ff7e2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin.js +2 -4
- package/dist/cli/index.js +1396 -83
- package/dist/config.js +19 -1
- package/dist/routes.js +179 -12
- package/dist/vite/cloudflare.js +155 -17
- package/dist/vite.js +2742 -10
- package/package.json +9 -9
- package/dist/build-7TXNW2O3.js +0 -239
- package/dist/chunk-FJ4CMFCI.js +0 -49
- package/dist/chunk-OQBNE3LV.js +0 -219
- package/dist/chunk-PR3MIATB.js +0 -57
- package/dist/chunk-RXPOXUKM.js +0 -2626
- package/dist/chunk-SSBSSZ6H.js +0 -31
- package/dist/chunk-YZMCCARW.js +0 -81
- package/dist/config/module-sync-enabled/false.cjs +0 -2
- package/dist/config/module-sync-enabled/true.js +0 -2
- package/dist/dev-COP3AUB5.js +0 -74
package/dist/chunk-RXPOXUKM.js
DELETED
|
@@ -1,2626 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @react-router/dev v0.0.0-experimental-e1f760554
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) Remix Software Inc.
|
|
5
|
-
*
|
|
6
|
-
* This source code is licensed under the MIT license found in the
|
|
7
|
-
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
-
*
|
|
9
|
-
* @license MIT
|
|
10
|
-
*/
|
|
11
|
-
import {
|
|
12
|
-
configRoutesToRouteManifest,
|
|
13
|
-
setAppDirectory,
|
|
14
|
-
validateRouteConfig
|
|
15
|
-
} from "./chunk-OQBNE3LV.js";
|
|
16
|
-
import {
|
|
17
|
-
fromNodeRequest,
|
|
18
|
-
toNodeRequest
|
|
19
|
-
} from "./chunk-YZMCCARW.js";
|
|
20
|
-
import {
|
|
21
|
-
getVite,
|
|
22
|
-
isReactRouterRepo,
|
|
23
|
-
preloadVite
|
|
24
|
-
} from "./chunk-PR3MIATB.js";
|
|
25
|
-
import {
|
|
26
|
-
invariant
|
|
27
|
-
} from "./chunk-SSBSSZ6H.js";
|
|
28
|
-
|
|
29
|
-
// config/config.ts
|
|
30
|
-
import fs from "node:fs";
|
|
31
|
-
import { execSync } from "node:child_process";
|
|
32
|
-
import { createRequire } from "node:module";
|
|
33
|
-
import PackageJson from "@npmcli/package-json";
|
|
34
|
-
|
|
35
|
-
// vite/vite-node.ts
|
|
36
|
-
import { ViteNodeServer } from "vite-node/server";
|
|
37
|
-
import { ViteNodeRunner } from "vite-node/client";
|
|
38
|
-
import { installSourcemapsSupport } from "vite-node/source-map";
|
|
39
|
-
async function createContext(viteConfig = {}) {
|
|
40
|
-
await preloadVite();
|
|
41
|
-
const vite = getVite();
|
|
42
|
-
const devServer = await vite.createServer(
|
|
43
|
-
vite.mergeConfig(
|
|
44
|
-
{
|
|
45
|
-
server: {
|
|
46
|
-
preTransformRequests: false,
|
|
47
|
-
hmr: false
|
|
48
|
-
},
|
|
49
|
-
optimizeDeps: {
|
|
50
|
-
noDiscovery: true
|
|
51
|
-
},
|
|
52
|
-
configFile: false,
|
|
53
|
-
envFile: false,
|
|
54
|
-
plugins: []
|
|
55
|
-
},
|
|
56
|
-
viteConfig
|
|
57
|
-
)
|
|
58
|
-
);
|
|
59
|
-
await devServer.pluginContainer.buildStart({});
|
|
60
|
-
const server = new ViteNodeServer(devServer);
|
|
61
|
-
installSourcemapsSupport({
|
|
62
|
-
getSourceMap: (source) => server.getSourceMap(source)
|
|
63
|
-
});
|
|
64
|
-
const runner = new ViteNodeRunner({
|
|
65
|
-
root: devServer.config.root,
|
|
66
|
-
base: devServer.config.base,
|
|
67
|
-
fetchModule(id) {
|
|
68
|
-
return server.fetchModule(id);
|
|
69
|
-
},
|
|
70
|
-
resolveId(id, importer) {
|
|
71
|
-
return server.resolveId(id, importer);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
return { devServer, server, runner };
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// config/config.ts
|
|
78
|
-
import path from "pathe";
|
|
79
|
-
import chokidar from "chokidar";
|
|
80
|
-
import colors from "picocolors";
|
|
81
|
-
import pick from "lodash/pick.js";
|
|
82
|
-
import omit from "lodash/omit.js";
|
|
83
|
-
import cloneDeep from "lodash/cloneDeep.js";
|
|
84
|
-
import isEqual from "lodash/isEqual.js";
|
|
85
|
-
|
|
86
|
-
// cli/detectPackageManager.ts
|
|
87
|
-
var detectPackageManager = () => {
|
|
88
|
-
let { npm_config_user_agent } = process.env;
|
|
89
|
-
if (!npm_config_user_agent) return void 0;
|
|
90
|
-
try {
|
|
91
|
-
let pkgManager = npm_config_user_agent.split("/")[0];
|
|
92
|
-
if (pkgManager === "npm") return "npm";
|
|
93
|
-
if (pkgManager === "pnpm") return "pnpm";
|
|
94
|
-
if (pkgManager === "yarn") return "yarn";
|
|
95
|
-
if (pkgManager === "bun") return "bun";
|
|
96
|
-
return void 0;
|
|
97
|
-
} catch {
|
|
98
|
-
return void 0;
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// config/config.ts
|
|
103
|
-
var require2 = createRequire(import.meta.url);
|
|
104
|
-
var excludedConfigPresetKeys = ["presets"];
|
|
105
|
-
var branchRouteProperties = [
|
|
106
|
-
"id",
|
|
107
|
-
"path",
|
|
108
|
-
"file",
|
|
109
|
-
"index"
|
|
110
|
-
];
|
|
111
|
-
var configRouteToBranchRoute = (configRoute) => pick(configRoute, branchRouteProperties);
|
|
112
|
-
var mergeReactRouterConfig = (...configs) => {
|
|
113
|
-
let reducer = (configA, configB) => {
|
|
114
|
-
let mergeRequired = (key) => configA[key] !== void 0 && configB[key] !== void 0;
|
|
115
|
-
return {
|
|
116
|
-
...configA,
|
|
117
|
-
...configB,
|
|
118
|
-
...mergeRequired("buildEnd") ? {
|
|
119
|
-
buildEnd: async (...args) => {
|
|
120
|
-
await Promise.all([
|
|
121
|
-
configA.buildEnd?.(...args),
|
|
122
|
-
configB.buildEnd?.(...args)
|
|
123
|
-
]);
|
|
124
|
-
}
|
|
125
|
-
} : {},
|
|
126
|
-
...mergeRequired("future") ? {
|
|
127
|
-
future: {
|
|
128
|
-
...configA.future,
|
|
129
|
-
...configB.future
|
|
130
|
-
}
|
|
131
|
-
} : {},
|
|
132
|
-
...mergeRequired("presets") ? {
|
|
133
|
-
presets: [...configA.presets ?? [], ...configB.presets ?? []]
|
|
134
|
-
} : {}
|
|
135
|
-
};
|
|
136
|
-
};
|
|
137
|
-
return configs.reduce(reducer, {});
|
|
138
|
-
};
|
|
139
|
-
var deepFreeze = (o) => {
|
|
140
|
-
Object.freeze(o);
|
|
141
|
-
let oIsFunction = typeof o === "function";
|
|
142
|
-
let hasOwnProp = Object.prototype.hasOwnProperty;
|
|
143
|
-
Object.getOwnPropertyNames(o).forEach(function(prop) {
|
|
144
|
-
if (hasOwnProp.call(o, prop) && (oIsFunction ? prop !== "caller" && prop !== "callee" && prop !== "arguments" : true) && o[prop] !== null && (typeof o[prop] === "object" || typeof o[prop] === "function") && !Object.isFrozen(o[prop])) {
|
|
145
|
-
deepFreeze(o[prop]);
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
return o;
|
|
149
|
-
};
|
|
150
|
-
function ok(value) {
|
|
151
|
-
return { ok: true, value };
|
|
152
|
-
}
|
|
153
|
-
function err(error) {
|
|
154
|
-
return { ok: false, error };
|
|
155
|
-
}
|
|
156
|
-
async function resolveConfig({
|
|
157
|
-
root,
|
|
158
|
-
viteNodeContext,
|
|
159
|
-
reactRouterConfigFile
|
|
160
|
-
}) {
|
|
161
|
-
let reactRouterUserConfig = {};
|
|
162
|
-
if (reactRouterConfigFile) {
|
|
163
|
-
try {
|
|
164
|
-
if (!fs.existsSync(reactRouterConfigFile)) {
|
|
165
|
-
return err(`${reactRouterConfigFile} no longer exists`);
|
|
166
|
-
}
|
|
167
|
-
let configModule = await viteNodeContext.runner.executeFile(
|
|
168
|
-
reactRouterConfigFile
|
|
169
|
-
);
|
|
170
|
-
if (configModule.default === void 0) {
|
|
171
|
-
return err(`${reactRouterConfigFile} must provide a default export`);
|
|
172
|
-
}
|
|
173
|
-
if (typeof configModule.default !== "object") {
|
|
174
|
-
return err(`${reactRouterConfigFile} must export a config`);
|
|
175
|
-
}
|
|
176
|
-
reactRouterUserConfig = configModule.default;
|
|
177
|
-
} catch (error) {
|
|
178
|
-
return err(`Error loading ${reactRouterConfigFile}: ${error}`);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
reactRouterUserConfig = deepFreeze(cloneDeep(reactRouterUserConfig));
|
|
182
|
-
let presets = (await Promise.all(
|
|
183
|
-
(reactRouterUserConfig.presets ?? []).map(async (preset) => {
|
|
184
|
-
if (!preset.name) {
|
|
185
|
-
throw new Error(
|
|
186
|
-
"React Router presets must have a `name` property defined."
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
if (!preset.reactRouterConfig) {
|
|
190
|
-
return null;
|
|
191
|
-
}
|
|
192
|
-
let configPreset = omit(
|
|
193
|
-
await preset.reactRouterConfig({ reactRouterUserConfig }),
|
|
194
|
-
excludedConfigPresetKeys
|
|
195
|
-
);
|
|
196
|
-
return configPreset;
|
|
197
|
-
})
|
|
198
|
-
)).filter(function isNotNull(value) {
|
|
199
|
-
return value !== null;
|
|
200
|
-
});
|
|
201
|
-
let defaults = {
|
|
202
|
-
basename: "/",
|
|
203
|
-
buildDirectory: "build",
|
|
204
|
-
serverBuildFile: "index.js",
|
|
205
|
-
serverModuleFormat: "esm",
|
|
206
|
-
ssr: true
|
|
207
|
-
};
|
|
208
|
-
let {
|
|
209
|
-
appDirectory: userAppDirectory,
|
|
210
|
-
basename: basename2,
|
|
211
|
-
buildDirectory: userBuildDirectory,
|
|
212
|
-
buildEnd,
|
|
213
|
-
prerender,
|
|
214
|
-
serverBuildFile,
|
|
215
|
-
serverBundles,
|
|
216
|
-
serverModuleFormat,
|
|
217
|
-
ssr
|
|
218
|
-
} = {
|
|
219
|
-
...defaults,
|
|
220
|
-
// Default values should be completely overridden by user/preset config, not merged
|
|
221
|
-
...mergeReactRouterConfig(...presets, reactRouterUserConfig)
|
|
222
|
-
};
|
|
223
|
-
if (!ssr && serverBundles) {
|
|
224
|
-
serverBundles = void 0;
|
|
225
|
-
}
|
|
226
|
-
let isValidPrerenderConfig = prerender == null || typeof prerender === "boolean" || Array.isArray(prerender) || typeof prerender === "function";
|
|
227
|
-
if (!isValidPrerenderConfig) {
|
|
228
|
-
return err(
|
|
229
|
-
"The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
let appDirectory = path.resolve(root, userAppDirectory || "app");
|
|
233
|
-
let buildDirectory = path.resolve(root, userBuildDirectory);
|
|
234
|
-
let rootRouteFile = findEntry(appDirectory, "root");
|
|
235
|
-
if (!rootRouteFile) {
|
|
236
|
-
let rootRouteDisplayPath = path.relative(
|
|
237
|
-
root,
|
|
238
|
-
path.join(appDirectory, "root.tsx")
|
|
239
|
-
);
|
|
240
|
-
return err(
|
|
241
|
-
`Could not find a root route module in the app directory as "${rootRouteDisplayPath}"`
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
let routes = {
|
|
245
|
-
root: { path: "", id: "root", file: rootRouteFile }
|
|
246
|
-
};
|
|
247
|
-
let routeConfigFile = findEntry(appDirectory, "routes");
|
|
248
|
-
try {
|
|
249
|
-
if (!routeConfigFile) {
|
|
250
|
-
let routeConfigDisplayPath = path.relative(
|
|
251
|
-
root,
|
|
252
|
-
path.join(appDirectory, "routes.ts")
|
|
253
|
-
);
|
|
254
|
-
return err(`Route config file not found at "${routeConfigDisplayPath}".`);
|
|
255
|
-
}
|
|
256
|
-
setAppDirectory(appDirectory);
|
|
257
|
-
let routeConfigExport = (await viteNodeContext.runner.executeFile(
|
|
258
|
-
path.join(appDirectory, routeConfigFile)
|
|
259
|
-
)).default;
|
|
260
|
-
let routeConfig = await routeConfigExport;
|
|
261
|
-
let result = validateRouteConfig({
|
|
262
|
-
routeConfigFile,
|
|
263
|
-
routeConfig
|
|
264
|
-
});
|
|
265
|
-
if (!result.valid) {
|
|
266
|
-
return err(result.message);
|
|
267
|
-
}
|
|
268
|
-
routes = {
|
|
269
|
-
...routes,
|
|
270
|
-
...configRoutesToRouteManifest(appDirectory, routeConfig)
|
|
271
|
-
};
|
|
272
|
-
} catch (error) {
|
|
273
|
-
return err(
|
|
274
|
-
[
|
|
275
|
-
colors.red(`Route config in "${routeConfigFile}" is invalid.`),
|
|
276
|
-
"",
|
|
277
|
-
error.loc?.file && error.loc?.column && error.frame ? [
|
|
278
|
-
path.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
|
|
279
|
-
error.frame.trim?.()
|
|
280
|
-
] : error.stack
|
|
281
|
-
].flat().join("\n")
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
let future = {
|
|
285
|
-
unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false
|
|
286
|
-
};
|
|
287
|
-
let reactRouterConfig = deepFreeze({
|
|
288
|
-
appDirectory,
|
|
289
|
-
basename: basename2,
|
|
290
|
-
buildDirectory,
|
|
291
|
-
buildEnd,
|
|
292
|
-
future,
|
|
293
|
-
prerender,
|
|
294
|
-
routes,
|
|
295
|
-
serverBuildFile,
|
|
296
|
-
serverBundles,
|
|
297
|
-
serverModuleFormat,
|
|
298
|
-
ssr
|
|
299
|
-
});
|
|
300
|
-
for (let preset of reactRouterUserConfig.presets ?? []) {
|
|
301
|
-
await preset.reactRouterConfigResolved?.({ reactRouterConfig });
|
|
302
|
-
}
|
|
303
|
-
return ok(reactRouterConfig);
|
|
304
|
-
}
|
|
305
|
-
async function createConfigLoader({
|
|
306
|
-
rootDirectory: root,
|
|
307
|
-
watch: watch2
|
|
308
|
-
}) {
|
|
309
|
-
root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
|
|
310
|
-
let viteNodeContext = await createContext({
|
|
311
|
-
root,
|
|
312
|
-
mode: watch2 ? "development" : "production",
|
|
313
|
-
server: !watch2 ? { watch: null } : {},
|
|
314
|
-
ssr: {
|
|
315
|
-
external: ssrExternals
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
let reactRouterConfigFile = findEntry(root, "react-router.config", {
|
|
319
|
-
absolute: true
|
|
320
|
-
});
|
|
321
|
-
let getConfig = () => resolveConfig({ root, viteNodeContext, reactRouterConfigFile });
|
|
322
|
-
let appDirectory;
|
|
323
|
-
let initialConfigResult = await getConfig();
|
|
324
|
-
if (!initialConfigResult.ok) {
|
|
325
|
-
throw new Error(initialConfigResult.error);
|
|
326
|
-
}
|
|
327
|
-
appDirectory = initialConfigResult.value.appDirectory;
|
|
328
|
-
let lastConfig = initialConfigResult.value;
|
|
329
|
-
let fsWatcher;
|
|
330
|
-
let changeHandlers = [];
|
|
331
|
-
return {
|
|
332
|
-
getConfig,
|
|
333
|
-
onChange: (handler) => {
|
|
334
|
-
if (!watch2) {
|
|
335
|
-
throw new Error(
|
|
336
|
-
"onChange is not supported when watch mode is disabled"
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
changeHandlers.push(handler);
|
|
340
|
-
if (!fsWatcher) {
|
|
341
|
-
fsWatcher = chokidar.watch(
|
|
342
|
-
[
|
|
343
|
-
...reactRouterConfigFile ? [reactRouterConfigFile] : [],
|
|
344
|
-
appDirectory
|
|
345
|
-
],
|
|
346
|
-
{ ignoreInitial: true }
|
|
347
|
-
);
|
|
348
|
-
fsWatcher.on("all", async (...args) => {
|
|
349
|
-
let [event, rawFilepath] = args;
|
|
350
|
-
let filepath = path.normalize(rawFilepath);
|
|
351
|
-
let appFileAddedOrRemoved = appDirectory && (event === "add" || event === "unlink") && filepath.startsWith(path.normalize(appDirectory));
|
|
352
|
-
let configCodeUpdated = Boolean(
|
|
353
|
-
viteNodeContext.devServer?.moduleGraph.getModuleById(filepath)
|
|
354
|
-
);
|
|
355
|
-
if (configCodeUpdated || appFileAddedOrRemoved) {
|
|
356
|
-
viteNodeContext.devServer?.moduleGraph.invalidateAll();
|
|
357
|
-
viteNodeContext.runner?.moduleCache.clear();
|
|
358
|
-
}
|
|
359
|
-
if (appFileAddedOrRemoved || configCodeUpdated) {
|
|
360
|
-
let result = await getConfig();
|
|
361
|
-
let configChanged = result.ok && !isEqual(lastConfig, result.value);
|
|
362
|
-
let routeConfigChanged = result.ok && !isEqual(lastConfig?.routes, result.value.routes);
|
|
363
|
-
for (let handler2 of changeHandlers) {
|
|
364
|
-
handler2({
|
|
365
|
-
result,
|
|
366
|
-
configCodeUpdated,
|
|
367
|
-
configChanged,
|
|
368
|
-
routeConfigChanged,
|
|
369
|
-
path: filepath,
|
|
370
|
-
event
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
if (result.ok) {
|
|
374
|
-
lastConfig = result.value;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
return () => {
|
|
380
|
-
changeHandlers = changeHandlers.filter(
|
|
381
|
-
(changeHandler) => changeHandler !== handler
|
|
382
|
-
);
|
|
383
|
-
};
|
|
384
|
-
},
|
|
385
|
-
close: async () => {
|
|
386
|
-
changeHandlers = [];
|
|
387
|
-
await viteNodeContext.devServer.close();
|
|
388
|
-
await fsWatcher?.close();
|
|
389
|
-
}
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
async function resolveEntryFiles({
|
|
393
|
-
rootDirectory,
|
|
394
|
-
reactRouterConfig
|
|
395
|
-
}) {
|
|
396
|
-
let { appDirectory } = reactRouterConfig;
|
|
397
|
-
let defaultsDirectory = path.resolve(
|
|
398
|
-
path.dirname(require2.resolve("@react-router/dev/package.json")),
|
|
399
|
-
"dist",
|
|
400
|
-
"config",
|
|
401
|
-
"defaults"
|
|
402
|
-
);
|
|
403
|
-
let userEntryClientFile = findEntry(appDirectory, "entry.client");
|
|
404
|
-
let userEntryServerFile = findEntry(appDirectory, "entry.server");
|
|
405
|
-
let entryServerFile;
|
|
406
|
-
let entryClientFile = userEntryClientFile || "entry.client.tsx";
|
|
407
|
-
let pkgJson = await PackageJson.load(rootDirectory);
|
|
408
|
-
let deps = pkgJson.content.dependencies ?? {};
|
|
409
|
-
if (userEntryServerFile) {
|
|
410
|
-
entryServerFile = userEntryServerFile;
|
|
411
|
-
} else {
|
|
412
|
-
if (!deps["@react-router/node"]) {
|
|
413
|
-
throw new Error(
|
|
414
|
-
`Could not determine server runtime. Please install @react-router/node, or provide a custom entry.server.tsx/jsx file in your app directory.`
|
|
415
|
-
);
|
|
416
|
-
}
|
|
417
|
-
if (!deps["isbot"]) {
|
|
418
|
-
console.log(
|
|
419
|
-
"adding `isbot@5` to your package.json, you should commit this change"
|
|
420
|
-
);
|
|
421
|
-
pkgJson.update({
|
|
422
|
-
dependencies: {
|
|
423
|
-
...pkgJson.content.dependencies,
|
|
424
|
-
isbot: "^5"
|
|
425
|
-
}
|
|
426
|
-
});
|
|
427
|
-
await pkgJson.save();
|
|
428
|
-
let packageManager = detectPackageManager() ?? "npm";
|
|
429
|
-
execSync(`${packageManager} install`, {
|
|
430
|
-
cwd: rootDirectory,
|
|
431
|
-
stdio: "inherit"
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
entryServerFile = `entry.server.node.tsx`;
|
|
435
|
-
}
|
|
436
|
-
let entryClientFilePath = userEntryClientFile ? path.resolve(reactRouterConfig.appDirectory, userEntryClientFile) : path.resolve(defaultsDirectory, entryClientFile);
|
|
437
|
-
let entryServerFilePath = userEntryServerFile ? path.resolve(reactRouterConfig.appDirectory, userEntryServerFile) : path.resolve(defaultsDirectory, entryServerFile);
|
|
438
|
-
return { entryClientFilePath, entryServerFilePath };
|
|
439
|
-
}
|
|
440
|
-
var ssrExternals = isReactRouterRepo() ? [
|
|
441
|
-
// This is only needed within this repo because these packages
|
|
442
|
-
// are linked to a directory outside of node_modules so Vite
|
|
443
|
-
// treats them as internal code by default.
|
|
444
|
-
"react-router",
|
|
445
|
-
"react-router-dom",
|
|
446
|
-
"@react-router/architect",
|
|
447
|
-
"@react-router/cloudflare",
|
|
448
|
-
"@react-router/dev",
|
|
449
|
-
"@react-router/express",
|
|
450
|
-
"@react-router/node",
|
|
451
|
-
"@react-router/serve"
|
|
452
|
-
] : void 0;
|
|
453
|
-
var entryExts = [".js", ".jsx", ".ts", ".tsx"];
|
|
454
|
-
function findEntry(dir, basename2, options) {
|
|
455
|
-
for (let ext of entryExts) {
|
|
456
|
-
let file = path.resolve(dir, basename2 + ext);
|
|
457
|
-
if (fs.existsSync(file)) {
|
|
458
|
-
return options?.absolute ?? false ? file : path.relative(dir, file);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
return void 0;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// vite/plugin.ts
|
|
465
|
-
import { createRequire as createRequire3 } from "node:module";
|
|
466
|
-
import { createHash } from "node:crypto";
|
|
467
|
-
import * as path4 from "node:path";
|
|
468
|
-
import * as url from "node:url";
|
|
469
|
-
import fse from "fs-extra";
|
|
470
|
-
import * as babel from "@babel/core";
|
|
471
|
-
import {
|
|
472
|
-
unstable_setDevServerHooks as setDevServerHooks,
|
|
473
|
-
createRequestHandler,
|
|
474
|
-
matchRoutes as matchRoutes2
|
|
475
|
-
} from "react-router";
|
|
476
|
-
import {
|
|
477
|
-
init as initEsModuleLexer,
|
|
478
|
-
parse as esModuleLexer
|
|
479
|
-
} from "es-module-lexer";
|
|
480
|
-
import jsesc from "jsesc";
|
|
481
|
-
import colors2 from "picocolors";
|
|
482
|
-
|
|
483
|
-
// typegen/index.ts
|
|
484
|
-
import fs2 from "node:fs";
|
|
485
|
-
import * as Path3 from "pathe";
|
|
486
|
-
import pc from "picocolors";
|
|
487
|
-
|
|
488
|
-
// typegen/generate.ts
|
|
489
|
-
import ts from "dedent";
|
|
490
|
-
import * as Path2 from "pathe";
|
|
491
|
-
import * as Pathe2 from "pathe/utils";
|
|
492
|
-
|
|
493
|
-
// typegen/paths.ts
|
|
494
|
-
import * as Path from "pathe";
|
|
495
|
-
import * as Pathe from "pathe/utils";
|
|
496
|
-
function getTypesDir(ctx) {
|
|
497
|
-
return Path.join(ctx.rootDirectory, ".react-router/types");
|
|
498
|
-
}
|
|
499
|
-
function getTypesPath(ctx, route) {
|
|
500
|
-
return Path.join(
|
|
501
|
-
getTypesDir(ctx),
|
|
502
|
-
Path.relative(ctx.rootDirectory, ctx.config.appDirectory),
|
|
503
|
-
Path.dirname(route.file),
|
|
504
|
-
"+types/" + Pathe.filename(route.file) + ".ts"
|
|
505
|
-
);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
// typegen/generate.ts
|
|
509
|
-
function generate(ctx, route) {
|
|
510
|
-
const lineage = getRouteLineage(ctx.config.routes, route);
|
|
511
|
-
const urlpath = lineage.map((route2) => route2.path).join("/");
|
|
512
|
-
const typesPath = getTypesPath(ctx, route);
|
|
513
|
-
const parents = lineage.slice(0, -1);
|
|
514
|
-
const parentTypeImports = parents.map((parent, i) => {
|
|
515
|
-
const rel = Path2.relative(
|
|
516
|
-
Path2.dirname(typesPath),
|
|
517
|
-
getTypesPath(ctx, parent)
|
|
518
|
-
);
|
|
519
|
-
const indent = i === 0 ? "" : " ".repeat(2);
|
|
520
|
-
let source = noExtension(rel);
|
|
521
|
-
if (!source.startsWith("../")) source = "./" + source;
|
|
522
|
-
return `${indent}import type { Info as Parent${i} } from "${source}.js"`;
|
|
523
|
-
}).join("\n");
|
|
524
|
-
return ts`
|
|
525
|
-
// React Router generated types for route:
|
|
526
|
-
// ${route.file}
|
|
527
|
-
|
|
528
|
-
import type * as T from "react-router/route-module"
|
|
529
|
-
|
|
530
|
-
${parentTypeImports}
|
|
531
|
-
|
|
532
|
-
type Module = typeof import("../${Pathe2.filename(route.file)}.js")
|
|
533
|
-
|
|
534
|
-
export type Info = {
|
|
535
|
-
parents: [${parents.map((_, i) => `Parent${i}`).join(", ")}],
|
|
536
|
-
id: "${route.id}"
|
|
537
|
-
file: "${route.file}"
|
|
538
|
-
path: "${route.path}"
|
|
539
|
-
params: {${formatParamProperties(
|
|
540
|
-
urlpath
|
|
541
|
-
)}} & { [key: string]: string | undefined }
|
|
542
|
-
module: Module
|
|
543
|
-
loaderData: T.CreateLoaderData<Module>
|
|
544
|
-
actionData: T.CreateActionData<Module>
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
export namespace Route {
|
|
548
|
-
export type LinkDescriptors = T.LinkDescriptors
|
|
549
|
-
export type LinksFunction = () => LinkDescriptors
|
|
550
|
-
|
|
551
|
-
export type MetaArgs = T.CreateMetaArgs<Info>
|
|
552
|
-
export type MetaDescriptors = T.MetaDescriptors
|
|
553
|
-
export type MetaFunction = (args: MetaArgs) => MetaDescriptors
|
|
554
|
-
|
|
555
|
-
export type HeadersArgs = T.HeadersArgs
|
|
556
|
-
export type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit
|
|
557
|
-
|
|
558
|
-
export type LoaderArgs = T.CreateServerLoaderArgs<Info>
|
|
559
|
-
export type ClientLoaderArgs = T.CreateClientLoaderArgs<Info>
|
|
560
|
-
export type ActionArgs = T.CreateServerActionArgs<Info>
|
|
561
|
-
export type ClientActionArgs = T.CreateClientActionArgs<Info>
|
|
562
|
-
|
|
563
|
-
export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Info>
|
|
564
|
-
export type ComponentProps = T.CreateComponentProps<Info>
|
|
565
|
-
export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Info>
|
|
566
|
-
}
|
|
567
|
-
`;
|
|
568
|
-
}
|
|
569
|
-
var noExtension = (path5) => Path2.join(Path2.dirname(path5), Pathe2.filename(path5));
|
|
570
|
-
function getRouteLineage(routes, route) {
|
|
571
|
-
const result = [];
|
|
572
|
-
while (route) {
|
|
573
|
-
result.push(route);
|
|
574
|
-
if (!route.parentId) break;
|
|
575
|
-
route = routes[route.parentId];
|
|
576
|
-
}
|
|
577
|
-
result.reverse();
|
|
578
|
-
return result;
|
|
579
|
-
}
|
|
580
|
-
function formatParamProperties(urlpath) {
|
|
581
|
-
const params = parseParams(urlpath);
|
|
582
|
-
const properties = Object.entries(params).map(([name, values]) => {
|
|
583
|
-
if (values.length === 1) {
|
|
584
|
-
const isOptional = values[0];
|
|
585
|
-
return isOptional ? `"${name}"?: string` : `"${name}": string`;
|
|
586
|
-
}
|
|
587
|
-
const items = values.map(
|
|
588
|
-
(isOptional) => isOptional ? "string | undefined" : "string"
|
|
589
|
-
);
|
|
590
|
-
return `"${name}": [${items.join(", ")}]`;
|
|
591
|
-
});
|
|
592
|
-
return properties.join("; ");
|
|
593
|
-
}
|
|
594
|
-
function parseParams(urlpath) {
|
|
595
|
-
const result = {};
|
|
596
|
-
let segments = urlpath.split("/");
|
|
597
|
-
segments.forEach((segment) => {
|
|
598
|
-
const match = segment.match(/^:([\w-]+)(\?)?/);
|
|
599
|
-
if (!match) return;
|
|
600
|
-
const param = match[1];
|
|
601
|
-
const isOptional = match[2] !== void 0;
|
|
602
|
-
result[param] ??= [];
|
|
603
|
-
result[param].push(isOptional);
|
|
604
|
-
return;
|
|
605
|
-
});
|
|
606
|
-
const hasSplat = segments.at(-1) === "*";
|
|
607
|
-
if (hasSplat) result["*"] = [false];
|
|
608
|
-
return result;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// typegen/index.ts
|
|
612
|
-
async function run(rootDirectory) {
|
|
613
|
-
const ctx = await createContext2({ rootDirectory, watch: false });
|
|
614
|
-
await writeAll(ctx);
|
|
615
|
-
}
|
|
616
|
-
async function watch(rootDirectory, { logger } = {}) {
|
|
617
|
-
const ctx = await createContext2({ rootDirectory, watch: true });
|
|
618
|
-
await writeAll(ctx);
|
|
619
|
-
logger?.info(pc.green("generated types"), { timestamp: true, clear: true });
|
|
620
|
-
ctx.configLoader.onChange(async ({ result, routeConfigChanged }) => {
|
|
621
|
-
if (!result.ok) {
|
|
622
|
-
logger?.error(pc.red(result.error), { timestamp: true, clear: true });
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
ctx.config = result.value;
|
|
626
|
-
if (routeConfigChanged) {
|
|
627
|
-
await writeAll(ctx);
|
|
628
|
-
logger?.info(pc.green("regenerated types"), {
|
|
629
|
-
timestamp: true,
|
|
630
|
-
clear: true
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
});
|
|
634
|
-
return {
|
|
635
|
-
close: async () => await ctx.configLoader.close()
|
|
636
|
-
};
|
|
637
|
-
}
|
|
638
|
-
async function createContext2({
|
|
639
|
-
rootDirectory,
|
|
640
|
-
watch: watch2
|
|
641
|
-
}) {
|
|
642
|
-
const configLoader = await createConfigLoader({ rootDirectory, watch: watch2 });
|
|
643
|
-
const configResult = await configLoader.getConfig();
|
|
644
|
-
if (!configResult.ok) {
|
|
645
|
-
throw new Error(configResult.error);
|
|
646
|
-
}
|
|
647
|
-
const config = configResult.value;
|
|
648
|
-
return {
|
|
649
|
-
configLoader,
|
|
650
|
-
rootDirectory,
|
|
651
|
-
config
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
async function writeAll(ctx) {
|
|
655
|
-
const typegenDir = getTypesDir(ctx);
|
|
656
|
-
fs2.rmSync(typegenDir, { recursive: true, force: true });
|
|
657
|
-
Object.values(ctx.config.routes).forEach((route) => {
|
|
658
|
-
const typesPath = getTypesPath(ctx, route);
|
|
659
|
-
const content = generate(ctx, route);
|
|
660
|
-
fs2.mkdirSync(Path3.dirname(typesPath), { recursive: true });
|
|
661
|
-
fs2.writeFileSync(typesPath, content);
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
// vite/babel.ts
|
|
666
|
-
import { createRequire as createRequire2 } from "node:module";
|
|
667
|
-
import { parse } from "@babel/parser";
|
|
668
|
-
import * as t from "@babel/types";
|
|
669
|
-
var require3 = createRequire2(import.meta.url);
|
|
670
|
-
var traverse = require3("@babel/traverse").default;
|
|
671
|
-
var generate2 = require3("@babel/generator").default;
|
|
672
|
-
|
|
673
|
-
// vite/styles.ts
|
|
674
|
-
import * as path3 from "node:path";
|
|
675
|
-
import { matchRoutes } from "react-router";
|
|
676
|
-
|
|
677
|
-
// vite/resolve-file-url.ts
|
|
678
|
-
import * as path2 from "node:path";
|
|
679
|
-
var resolveFileUrl = ({ rootDirectory }, filePath) => {
|
|
680
|
-
let vite = getVite();
|
|
681
|
-
let relativePath = path2.relative(rootDirectory, filePath);
|
|
682
|
-
let isWithinRoot = !relativePath.startsWith("..") && !path2.isAbsolute(relativePath);
|
|
683
|
-
if (!isWithinRoot) {
|
|
684
|
-
return path2.posix.join("/@fs", vite.normalizePath(filePath));
|
|
685
|
-
}
|
|
686
|
-
return "/" + vite.normalizePath(relativePath);
|
|
687
|
-
};
|
|
688
|
-
|
|
689
|
-
// vite/styles.ts
|
|
690
|
-
var cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
|
|
691
|
-
var cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
|
|
692
|
-
var isCssFile = (file) => cssFileRegExp.test(file);
|
|
693
|
-
var isCssModulesFile = (file) => cssModulesRegExp.test(file);
|
|
694
|
-
var cssUrlParamsWithoutSideEffects = ["url", "inline", "raw", "inline-css"];
|
|
695
|
-
var isCssUrlWithoutSideEffects = (url2) => {
|
|
696
|
-
let queryString = url2.split("?")[1];
|
|
697
|
-
if (!queryString) {
|
|
698
|
-
return false;
|
|
699
|
-
}
|
|
700
|
-
let params = new URLSearchParams(queryString);
|
|
701
|
-
for (let paramWithoutSideEffects of cssUrlParamsWithoutSideEffects) {
|
|
702
|
-
if (
|
|
703
|
-
// Parameter is blank and not explicitly set, i.e. "?url", not "?url="
|
|
704
|
-
params.get(paramWithoutSideEffects) === "" && !url2.includes(`?${paramWithoutSideEffects}=`) && !url2.includes(`&${paramWithoutSideEffects}=`)
|
|
705
|
-
) {
|
|
706
|
-
return true;
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
return false;
|
|
710
|
-
};
|
|
711
|
-
var injectQuery = (url2, query) => url2.includes("?") ? url2.replace("?", `?${query}&`) : `${url2}?${query}`;
|
|
712
|
-
var getStylesForFiles = async ({
|
|
713
|
-
viteDevServer,
|
|
714
|
-
rootDirectory,
|
|
715
|
-
cssModulesManifest,
|
|
716
|
-
files
|
|
717
|
-
}) => {
|
|
718
|
-
let vite = getVite();
|
|
719
|
-
let viteMajor = parseInt(vite.version.split(".")[0], 10);
|
|
720
|
-
let styles = {};
|
|
721
|
-
let deps = /* @__PURE__ */ new Set();
|
|
722
|
-
try {
|
|
723
|
-
for (let file of files) {
|
|
724
|
-
let normalizedPath = path3.resolve(rootDirectory, file).replace(/\\/g, "/");
|
|
725
|
-
let node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
|
|
726
|
-
if (!node) {
|
|
727
|
-
try {
|
|
728
|
-
await viteDevServer.transformRequest(
|
|
729
|
-
resolveFileUrl({ rootDirectory }, normalizedPath)
|
|
730
|
-
);
|
|
731
|
-
} catch (err2) {
|
|
732
|
-
console.error(err2);
|
|
733
|
-
}
|
|
734
|
-
node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
|
|
735
|
-
}
|
|
736
|
-
if (!node) {
|
|
737
|
-
console.log(`Could not resolve module for file: ${file}`);
|
|
738
|
-
continue;
|
|
739
|
-
}
|
|
740
|
-
await findDeps(viteDevServer, node, deps);
|
|
741
|
-
}
|
|
742
|
-
} catch (err2) {
|
|
743
|
-
console.error(err2);
|
|
744
|
-
}
|
|
745
|
-
for (let dep of deps) {
|
|
746
|
-
if (dep.file && isCssFile(dep.file) && !isCssUrlWithoutSideEffects(dep.url)) {
|
|
747
|
-
try {
|
|
748
|
-
let css = isCssModulesFile(dep.file) ? cssModulesManifest[dep.file] : (await viteDevServer.ssrLoadModule(
|
|
749
|
-
// We need the ?inline query in Vite v6 when loading CSS in SSR
|
|
750
|
-
// since it does not expose the default export for CSS in a
|
|
751
|
-
// server environment. This is to align with non-SSR
|
|
752
|
-
// environments. For backwards compatibility with v5 we keep
|
|
753
|
-
// using the URL without ?inline query because the HMR code was
|
|
754
|
-
// relying on the implicit SSR-client module graph relationship.
|
|
755
|
-
viteMajor >= 6 ? injectQuery(dep.url, "inline") : dep.url
|
|
756
|
-
)).default;
|
|
757
|
-
if (css === void 0) {
|
|
758
|
-
throw new Error();
|
|
759
|
-
}
|
|
760
|
-
styles[dep.url] = css;
|
|
761
|
-
} catch {
|
|
762
|
-
console.warn(`Could not load ${dep.file}`);
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
return Object.entries(styles).map(([fileName, css], i) => [
|
|
767
|
-
`
|
|
768
|
-
/* ${fileName.replace(/\/\*/g, "/\\*").replace(/\*\//g, "*\\/")} */`,
|
|
769
|
-
css
|
|
770
|
-
]).flat().join("\n") || void 0;
|
|
771
|
-
};
|
|
772
|
-
var findDeps = async (vite, node, deps) => {
|
|
773
|
-
let branches = [];
|
|
774
|
-
async function addFromNode(node2) {
|
|
775
|
-
if (!deps.has(node2)) {
|
|
776
|
-
deps.add(node2);
|
|
777
|
-
await findDeps(vite, node2, deps);
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
async function addFromUrl(url2) {
|
|
781
|
-
let node2 = await vite.moduleGraph.getModuleByUrl(url2);
|
|
782
|
-
if (node2) {
|
|
783
|
-
await addFromNode(node2);
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
if (node.ssrTransformResult) {
|
|
787
|
-
if (node.ssrTransformResult.deps) {
|
|
788
|
-
node.ssrTransformResult.deps.forEach(
|
|
789
|
-
(url2) => branches.push(addFromUrl(url2))
|
|
790
|
-
);
|
|
791
|
-
}
|
|
792
|
-
} else {
|
|
793
|
-
node.importedModules.forEach((node2) => branches.push(addFromNode(node2)));
|
|
794
|
-
}
|
|
795
|
-
await Promise.all(branches);
|
|
796
|
-
};
|
|
797
|
-
var groupRoutesByParentId = (manifest) => {
|
|
798
|
-
let routes = {};
|
|
799
|
-
Object.values(manifest).forEach((route) => {
|
|
800
|
-
if (route) {
|
|
801
|
-
let parentId = route.parentId || "";
|
|
802
|
-
if (!routes[parentId]) {
|
|
803
|
-
routes[parentId] = [];
|
|
804
|
-
}
|
|
805
|
-
routes[parentId].push(route);
|
|
806
|
-
}
|
|
807
|
-
});
|
|
808
|
-
return routes;
|
|
809
|
-
};
|
|
810
|
-
var createRoutes = (manifest, parentId = "", routesByParentId = groupRoutesByParentId(manifest)) => {
|
|
811
|
-
return (routesByParentId[parentId] || []).map((route) => ({
|
|
812
|
-
...route,
|
|
813
|
-
children: createRoutes(manifest, route.id, routesByParentId)
|
|
814
|
-
}));
|
|
815
|
-
};
|
|
816
|
-
var getStylesForUrl = async ({
|
|
817
|
-
viteDevServer,
|
|
818
|
-
rootDirectory,
|
|
819
|
-
reactRouterConfig,
|
|
820
|
-
entryClientFilePath,
|
|
821
|
-
cssModulesManifest,
|
|
822
|
-
build,
|
|
823
|
-
url: url2
|
|
824
|
-
}) => {
|
|
825
|
-
if (url2 === void 0 || url2.includes("?_data=")) {
|
|
826
|
-
return void 0;
|
|
827
|
-
}
|
|
828
|
-
let routes = createRoutes(build.routes);
|
|
829
|
-
let appPath = path3.relative(process.cwd(), reactRouterConfig.appDirectory);
|
|
830
|
-
let documentRouteFiles = matchRoutes(routes, url2, build.basename)?.map(
|
|
831
|
-
(match) => path3.resolve(appPath, reactRouterConfig.routes[match.route.id].file)
|
|
832
|
-
) ?? [];
|
|
833
|
-
let styles = await getStylesForFiles({
|
|
834
|
-
viteDevServer,
|
|
835
|
-
rootDirectory,
|
|
836
|
-
cssModulesManifest,
|
|
837
|
-
files: [
|
|
838
|
-
// Always include the client entry file when crawling the module graph for CSS
|
|
839
|
-
path3.relative(rootDirectory, entryClientFilePath),
|
|
840
|
-
// Then include any styles from the matched routes
|
|
841
|
-
...documentRouteFiles
|
|
842
|
-
]
|
|
843
|
-
});
|
|
844
|
-
return styles;
|
|
845
|
-
};
|
|
846
|
-
|
|
847
|
-
// vite/virtual-module.ts
|
|
848
|
-
function create(name) {
|
|
849
|
-
let id = `virtual:react-router/${name}`;
|
|
850
|
-
return {
|
|
851
|
-
id,
|
|
852
|
-
resolvedId: `\0${id}`,
|
|
853
|
-
url: `/@id/__x00__${id}`
|
|
854
|
-
};
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
// vite/combine-urls.ts
|
|
858
|
-
function combineURLs(baseURL, relativeURL) {
|
|
859
|
-
return relativeURL ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL;
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
// vite/remove-exports.ts
|
|
863
|
-
import {
|
|
864
|
-
findReferencedIdentifiers,
|
|
865
|
-
deadCodeElimination
|
|
866
|
-
} from "babel-dead-code-elimination";
|
|
867
|
-
var removeExports = (ast, exportsToRemove) => {
|
|
868
|
-
let previouslyReferencedIdentifiers = findReferencedIdentifiers(ast);
|
|
869
|
-
let exportsFiltered = false;
|
|
870
|
-
let markedForRemoval = /* @__PURE__ */ new Set();
|
|
871
|
-
traverse(ast, {
|
|
872
|
-
ExportDeclaration(path5) {
|
|
873
|
-
if (path5.node.type === "ExportNamedDeclaration") {
|
|
874
|
-
if (path5.node.specifiers.length) {
|
|
875
|
-
path5.node.specifiers = path5.node.specifiers.filter((specifier) => {
|
|
876
|
-
if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier") {
|
|
877
|
-
if (exportsToRemove.includes(specifier.exported.name)) {
|
|
878
|
-
exportsFiltered = true;
|
|
879
|
-
return false;
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
return true;
|
|
883
|
-
});
|
|
884
|
-
if (path5.node.specifiers.length === 0) {
|
|
885
|
-
markedForRemoval.add(path5);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
if (path5.node.declaration?.type === "VariableDeclaration") {
|
|
889
|
-
let declaration = path5.node.declaration;
|
|
890
|
-
declaration.declarations = declaration.declarations.filter(
|
|
891
|
-
(declaration2) => {
|
|
892
|
-
if (declaration2.id.type === "Identifier" && exportsToRemove.includes(declaration2.id.name)) {
|
|
893
|
-
exportsFiltered = true;
|
|
894
|
-
return false;
|
|
895
|
-
}
|
|
896
|
-
if (declaration2.id.type === "ArrayPattern" || declaration2.id.type === "ObjectPattern") {
|
|
897
|
-
validateDestructuredExports(declaration2.id, exportsToRemove);
|
|
898
|
-
}
|
|
899
|
-
return true;
|
|
900
|
-
}
|
|
901
|
-
);
|
|
902
|
-
if (declaration.declarations.length === 0) {
|
|
903
|
-
markedForRemoval.add(path5);
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
if (path5.node.declaration?.type === "FunctionDeclaration") {
|
|
907
|
-
let id = path5.node.declaration.id;
|
|
908
|
-
if (id && exportsToRemove.includes(id.name)) {
|
|
909
|
-
markedForRemoval.add(path5);
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
if (path5.node.declaration?.type === "ClassDeclaration") {
|
|
913
|
-
let id = path5.node.declaration.id;
|
|
914
|
-
if (id && exportsToRemove.includes(id.name)) {
|
|
915
|
-
markedForRemoval.add(path5);
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
if (path5.node.type === "ExportDefaultDeclaration" && exportsToRemove.includes("default")) {
|
|
920
|
-
markedForRemoval.add(path5);
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
});
|
|
924
|
-
if (markedForRemoval.size > 0 || exportsFiltered) {
|
|
925
|
-
for (let path5 of markedForRemoval) {
|
|
926
|
-
path5.remove();
|
|
927
|
-
}
|
|
928
|
-
deadCodeElimination(ast, previouslyReferencedIdentifiers);
|
|
929
|
-
}
|
|
930
|
-
};
|
|
931
|
-
function validateDestructuredExports(id, exportsToRemove) {
|
|
932
|
-
if (id.type === "ArrayPattern") {
|
|
933
|
-
for (let element of id.elements) {
|
|
934
|
-
if (!element) {
|
|
935
|
-
continue;
|
|
936
|
-
}
|
|
937
|
-
if (element.type === "Identifier" && exportsToRemove.includes(element.name)) {
|
|
938
|
-
throw invalidDestructureError(element.name);
|
|
939
|
-
}
|
|
940
|
-
if (element.type === "RestElement" && element.argument.type === "Identifier" && exportsToRemove.includes(element.argument.name)) {
|
|
941
|
-
throw invalidDestructureError(element.argument.name);
|
|
942
|
-
}
|
|
943
|
-
if (element.type === "ArrayPattern" || element.type === "ObjectPattern") {
|
|
944
|
-
validateDestructuredExports(element, exportsToRemove);
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
if (id.type === "ObjectPattern") {
|
|
949
|
-
for (let property of id.properties) {
|
|
950
|
-
if (!property) {
|
|
951
|
-
continue;
|
|
952
|
-
}
|
|
953
|
-
if (property.type === "ObjectProperty" && property.key.type === "Identifier") {
|
|
954
|
-
if (property.value.type === "Identifier" && exportsToRemove.includes(property.value.name)) {
|
|
955
|
-
throw invalidDestructureError(property.value.name);
|
|
956
|
-
}
|
|
957
|
-
if (property.value.type === "ArrayPattern" || property.value.type === "ObjectPattern") {
|
|
958
|
-
validateDestructuredExports(property.value, exportsToRemove);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
if (property.type === "RestElement" && property.argument.type === "Identifier" && exportsToRemove.includes(property.argument.name)) {
|
|
962
|
-
throw invalidDestructureError(property.argument.name);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
function invalidDestructureError(name) {
|
|
968
|
-
return new Error(`Cannot remove destructured export "${name}"`);
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
// vite/with-props.ts
|
|
972
|
-
import dedent from "dedent";
|
|
973
|
-
var vmod = create("with-props");
|
|
974
|
-
var NAMED_COMPONENT_EXPORTS = ["HydrateFallback", "ErrorBoundary"];
|
|
975
|
-
var plugin = {
|
|
976
|
-
name: "react-router-with-props",
|
|
977
|
-
enforce: "pre",
|
|
978
|
-
resolveId(id) {
|
|
979
|
-
if (id === vmod.id) return vmod.resolvedId;
|
|
980
|
-
},
|
|
981
|
-
async load(id) {
|
|
982
|
-
if (id !== vmod.resolvedId) return;
|
|
983
|
-
return dedent`
|
|
984
|
-
import { createElement as h } from "react";
|
|
985
|
-
import { useActionData, useLoaderData, useMatches, useParams, useRouteError } from "react-router";
|
|
986
|
-
|
|
987
|
-
export function withComponentProps(Component) {
|
|
988
|
-
return function Wrapped() {
|
|
989
|
-
const props = {
|
|
990
|
-
params: useParams(),
|
|
991
|
-
loaderData: useLoaderData(),
|
|
992
|
-
actionData: useActionData(),
|
|
993
|
-
matches: useMatches(),
|
|
994
|
-
};
|
|
995
|
-
return h(Component, props);
|
|
996
|
-
};
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
export function withHydrateFallbackProps(HydrateFallback) {
|
|
1000
|
-
return function Wrapped() {
|
|
1001
|
-
const props = {
|
|
1002
|
-
params: useParams(),
|
|
1003
|
-
};
|
|
1004
|
-
return h(HydrateFallback, props);
|
|
1005
|
-
};
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
export function withErrorBoundaryProps(ErrorBoundary) {
|
|
1009
|
-
return function Wrapped() {
|
|
1010
|
-
const props = {
|
|
1011
|
-
params: useParams(),
|
|
1012
|
-
loaderData: useLoaderData(),
|
|
1013
|
-
actionData: useActionData(),
|
|
1014
|
-
error: useRouteError(),
|
|
1015
|
-
};
|
|
1016
|
-
return h(ErrorBoundary, props);
|
|
1017
|
-
};
|
|
1018
|
-
}
|
|
1019
|
-
`;
|
|
1020
|
-
}
|
|
1021
|
-
};
|
|
1022
|
-
var transform = (ast) => {
|
|
1023
|
-
const hocs = [];
|
|
1024
|
-
function getHocUid(path5, hocName) {
|
|
1025
|
-
const uid = path5.scope.generateUidIdentifier(hocName);
|
|
1026
|
-
hocs.push([hocName, uid]);
|
|
1027
|
-
return uid;
|
|
1028
|
-
}
|
|
1029
|
-
traverse(ast, {
|
|
1030
|
-
ExportDeclaration(path5) {
|
|
1031
|
-
if (path5.isExportDefaultDeclaration()) {
|
|
1032
|
-
const declaration = path5.get("declaration");
|
|
1033
|
-
const expr = declaration.isExpression() ? declaration.node : declaration.isFunctionDeclaration() ? toFunctionExpression(declaration.node) : void 0;
|
|
1034
|
-
if (expr) {
|
|
1035
|
-
const uid = getHocUid(path5, "withComponentProps");
|
|
1036
|
-
declaration.replaceWith(t.callExpression(uid, [expr]));
|
|
1037
|
-
}
|
|
1038
|
-
return;
|
|
1039
|
-
}
|
|
1040
|
-
if (path5.isExportNamedDeclaration()) {
|
|
1041
|
-
const decl = path5.get("declaration");
|
|
1042
|
-
if (decl.isVariableDeclaration()) {
|
|
1043
|
-
decl.get("declarations").forEach((varDeclarator) => {
|
|
1044
|
-
const id = varDeclarator.get("id");
|
|
1045
|
-
const init = varDeclarator.get("init");
|
|
1046
|
-
const expr = init.node;
|
|
1047
|
-
if (!expr) return;
|
|
1048
|
-
if (!id.isIdentifier()) return;
|
|
1049
|
-
const { name } = id.node;
|
|
1050
|
-
if (!NAMED_COMPONENT_EXPORTS.includes(name)) return;
|
|
1051
|
-
const uid = getHocUid(path5, `with${name}Props`);
|
|
1052
|
-
init.replaceWith(t.callExpression(uid, [expr]));
|
|
1053
|
-
});
|
|
1054
|
-
return;
|
|
1055
|
-
}
|
|
1056
|
-
if (decl.isFunctionDeclaration()) {
|
|
1057
|
-
const { id } = decl.node;
|
|
1058
|
-
if (!id) return;
|
|
1059
|
-
const { name } = id;
|
|
1060
|
-
if (!NAMED_COMPONENT_EXPORTS.includes(name)) return;
|
|
1061
|
-
const uid = getHocUid(path5, `with${name}Props`);
|
|
1062
|
-
decl.replaceWith(
|
|
1063
|
-
t.variableDeclaration("const", [
|
|
1064
|
-
t.variableDeclarator(
|
|
1065
|
-
t.identifier(name),
|
|
1066
|
-
t.callExpression(uid, [toFunctionExpression(decl.node)])
|
|
1067
|
-
)
|
|
1068
|
-
])
|
|
1069
|
-
);
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
});
|
|
1074
|
-
if (hocs.length > 0) {
|
|
1075
|
-
ast.program.body.unshift(
|
|
1076
|
-
t.importDeclaration(
|
|
1077
|
-
hocs.map(
|
|
1078
|
-
([name, identifier]) => t.importSpecifier(identifier, t.identifier(name))
|
|
1079
|
-
),
|
|
1080
|
-
t.stringLiteral(vmod.id)
|
|
1081
|
-
)
|
|
1082
|
-
);
|
|
1083
|
-
}
|
|
1084
|
-
};
|
|
1085
|
-
function toFunctionExpression(decl) {
|
|
1086
|
-
return t.functionExpression(
|
|
1087
|
-
decl.id,
|
|
1088
|
-
decl.params,
|
|
1089
|
-
decl.body,
|
|
1090
|
-
decl.generator,
|
|
1091
|
-
decl.async
|
|
1092
|
-
);
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
// vite/plugin.ts
|
|
1096
|
-
var require4 = createRequire3(import.meta.url);
|
|
1097
|
-
async function resolveViteConfig({
|
|
1098
|
-
configFile,
|
|
1099
|
-
mode,
|
|
1100
|
-
root
|
|
1101
|
-
}) {
|
|
1102
|
-
let vite = getVite();
|
|
1103
|
-
let viteConfig = await vite.resolveConfig(
|
|
1104
|
-
{ mode, configFile, root },
|
|
1105
|
-
"build",
|
|
1106
|
-
// command
|
|
1107
|
-
"production",
|
|
1108
|
-
// default mode
|
|
1109
|
-
"production"
|
|
1110
|
-
// default NODE_ENV
|
|
1111
|
-
);
|
|
1112
|
-
if (typeof viteConfig.build.manifest === "string") {
|
|
1113
|
-
throw new Error("Custom Vite manifest paths are not supported");
|
|
1114
|
-
}
|
|
1115
|
-
return viteConfig;
|
|
1116
|
-
}
|
|
1117
|
-
async function extractPluginContext(viteConfig) {
|
|
1118
|
-
return viteConfig["__reactRouterPluginContext"];
|
|
1119
|
-
}
|
|
1120
|
-
async function loadPluginContext({
|
|
1121
|
-
configFile,
|
|
1122
|
-
root
|
|
1123
|
-
}) {
|
|
1124
|
-
if (!root) {
|
|
1125
|
-
root = process.env.REACT_ROUTER_ROOT || process.cwd();
|
|
1126
|
-
}
|
|
1127
|
-
configFile = configFile ?? findConfig(root, "vite.config", [
|
|
1128
|
-
".ts",
|
|
1129
|
-
".cts",
|
|
1130
|
-
".mts",
|
|
1131
|
-
".js",
|
|
1132
|
-
".cjs",
|
|
1133
|
-
".mjs"
|
|
1134
|
-
]);
|
|
1135
|
-
if (!configFile) {
|
|
1136
|
-
console.error(colors2.red("Vite config file not found"));
|
|
1137
|
-
process.exit(1);
|
|
1138
|
-
}
|
|
1139
|
-
let viteConfig = await resolveViteConfig({ configFile, root });
|
|
1140
|
-
let ctx = await extractPluginContext(viteConfig);
|
|
1141
|
-
if (!ctx) {
|
|
1142
|
-
console.error(
|
|
1143
|
-
colors2.red("React Router Vite plugin not found in Vite config")
|
|
1144
|
-
);
|
|
1145
|
-
process.exit(1);
|
|
1146
|
-
}
|
|
1147
|
-
return ctx;
|
|
1148
|
-
}
|
|
1149
|
-
var SERVER_ONLY_ROUTE_EXPORTS = ["loader", "action", "headers"];
|
|
1150
|
-
var CLIENT_ROUTE_EXPORTS = [
|
|
1151
|
-
"clientAction",
|
|
1152
|
-
"clientLoader",
|
|
1153
|
-
"default",
|
|
1154
|
-
"ErrorBoundary",
|
|
1155
|
-
"handle",
|
|
1156
|
-
"HydrateFallback",
|
|
1157
|
-
"Layout",
|
|
1158
|
-
"links",
|
|
1159
|
-
"meta",
|
|
1160
|
-
"shouldRevalidate"
|
|
1161
|
-
];
|
|
1162
|
-
var BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
|
|
1163
|
-
var virtualHmrRuntime = create("hmr-runtime");
|
|
1164
|
-
var virtualInjectHmrRuntime = create("inject-hmr-runtime");
|
|
1165
|
-
var resolveRelativeRouteFilePath = (route, reactRouterConfig) => {
|
|
1166
|
-
let vite = getVite();
|
|
1167
|
-
let file = route.file;
|
|
1168
|
-
let fullPath = path4.resolve(reactRouterConfig.appDirectory, file);
|
|
1169
|
-
return vite.normalizePath(fullPath);
|
|
1170
|
-
};
|
|
1171
|
-
var virtual = {
|
|
1172
|
-
serverBuild: create("server-build"),
|
|
1173
|
-
serverManifest: create("server-manifest"),
|
|
1174
|
-
browserManifest: create("browser-manifest")
|
|
1175
|
-
};
|
|
1176
|
-
var invalidateVirtualModules = (viteDevServer) => {
|
|
1177
|
-
Object.values(virtual).forEach((vmod2) => {
|
|
1178
|
-
let mod = viteDevServer.moduleGraph.getModuleById(vmod2.resolvedId);
|
|
1179
|
-
if (mod) {
|
|
1180
|
-
viteDevServer.moduleGraph.invalidateModule(mod);
|
|
1181
|
-
}
|
|
1182
|
-
});
|
|
1183
|
-
};
|
|
1184
|
-
var getHash = (source, maxLength) => {
|
|
1185
|
-
let hash = createHash("sha256").update(source).digest("hex");
|
|
1186
|
-
return typeof maxLength === "number" ? hash.slice(0, maxLength) : hash;
|
|
1187
|
-
};
|
|
1188
|
-
var resolveChunk = (ctx, viteManifest, absoluteFilePath) => {
|
|
1189
|
-
let vite = getVite();
|
|
1190
|
-
let rootRelativeFilePath = vite.normalizePath(
|
|
1191
|
-
path4.relative(ctx.rootDirectory, absoluteFilePath)
|
|
1192
|
-
);
|
|
1193
|
-
let entryChunk = viteManifest[rootRelativeFilePath + BUILD_CLIENT_ROUTE_QUERY_STRING] ?? viteManifest[rootRelativeFilePath];
|
|
1194
|
-
if (!entryChunk) {
|
|
1195
|
-
let knownManifestKeys = Object.keys(viteManifest).map((key) => '"' + key + '"').join(", ");
|
|
1196
|
-
throw new Error(
|
|
1197
|
-
`No manifest entry found for "${rootRelativeFilePath}". Known manifest keys: ${knownManifestKeys}`
|
|
1198
|
-
);
|
|
1199
|
-
}
|
|
1200
|
-
return entryChunk;
|
|
1201
|
-
};
|
|
1202
|
-
var getReactRouterManifestBuildAssets = (ctx, viteManifest, entryFilePath, prependedAssetFilePaths = []) => {
|
|
1203
|
-
let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
|
|
1204
|
-
let prependedAssetChunks = prependedAssetFilePaths.map(
|
|
1205
|
-
(filePath) => resolveChunk(ctx, viteManifest, filePath)
|
|
1206
|
-
);
|
|
1207
|
-
let chunks = resolveDependantChunks(viteManifest, [
|
|
1208
|
-
...prependedAssetChunks,
|
|
1209
|
-
entryChunk
|
|
1210
|
-
]);
|
|
1211
|
-
return {
|
|
1212
|
-
module: `${ctx.publicPath}${entryChunk.file}`,
|
|
1213
|
-
imports: dedupe(chunks.flatMap((e) => e.imports ?? [])).map((imported) => {
|
|
1214
|
-
return `${ctx.publicPath}${viteManifest[imported].file}`;
|
|
1215
|
-
}) ?? [],
|
|
1216
|
-
css: dedupe(chunks.flatMap((e) => e.css ?? [])).map((href) => {
|
|
1217
|
-
return `${ctx.publicPath}${href}`;
|
|
1218
|
-
}) ?? []
|
|
1219
|
-
};
|
|
1220
|
-
};
|
|
1221
|
-
function resolveDependantChunks(viteManifest, entryChunks) {
|
|
1222
|
-
let chunks = /* @__PURE__ */ new Set();
|
|
1223
|
-
function walk(chunk) {
|
|
1224
|
-
if (chunks.has(chunk)) {
|
|
1225
|
-
return;
|
|
1226
|
-
}
|
|
1227
|
-
chunks.add(chunk);
|
|
1228
|
-
if (chunk.imports) {
|
|
1229
|
-
for (let importKey of chunk.imports) {
|
|
1230
|
-
walk(viteManifest[importKey]);
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
for (let entryChunk of entryChunks) {
|
|
1235
|
-
walk(entryChunk);
|
|
1236
|
-
}
|
|
1237
|
-
return Array.from(chunks);
|
|
1238
|
-
}
|
|
1239
|
-
function dedupe(array) {
|
|
1240
|
-
return [...new Set(array)];
|
|
1241
|
-
}
|
|
1242
|
-
var writeFileSafe = async (file, contents) => {
|
|
1243
|
-
await fse.ensureDir(path4.dirname(file));
|
|
1244
|
-
await fse.writeFile(file, contents);
|
|
1245
|
-
};
|
|
1246
|
-
var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
|
|
1247
|
-
let entries = await Promise.all(
|
|
1248
|
-
Object.entries(ctx.reactRouterConfig.routes).map(async ([key, route]) => {
|
|
1249
|
-
let sourceExports = await getRouteModuleExports(
|
|
1250
|
-
viteChildCompiler,
|
|
1251
|
-
ctx,
|
|
1252
|
-
route.file
|
|
1253
|
-
);
|
|
1254
|
-
return [key, sourceExports];
|
|
1255
|
-
})
|
|
1256
|
-
);
|
|
1257
|
-
return Object.fromEntries(entries);
|
|
1258
|
-
};
|
|
1259
|
-
var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
|
|
1260
|
-
if (!viteChildCompiler) {
|
|
1261
|
-
throw new Error("Vite child compiler not found");
|
|
1262
|
-
}
|
|
1263
|
-
let ssr = true;
|
|
1264
|
-
let { pluginContainer, moduleGraph } = viteChildCompiler;
|
|
1265
|
-
let routePath = path4.resolve(ctx.reactRouterConfig.appDirectory, routeFile);
|
|
1266
|
-
let url2 = resolveFileUrl(ctx, routePath);
|
|
1267
|
-
let resolveId = async () => {
|
|
1268
|
-
let result = await pluginContainer.resolveId(url2, void 0, { ssr });
|
|
1269
|
-
if (!result) throw new Error(`Could not resolve module ID for ${url2}`);
|
|
1270
|
-
return result.id;
|
|
1271
|
-
};
|
|
1272
|
-
let [id, code] = await Promise.all([
|
|
1273
|
-
resolveId(),
|
|
1274
|
-
readRouteFile?.() ?? fse.readFile(routePath, "utf-8"),
|
|
1275
|
-
// pluginContainer.transform(...) fails if we don't do this first:
|
|
1276
|
-
moduleGraph.ensureEntryFromUrl(url2, ssr)
|
|
1277
|
-
]);
|
|
1278
|
-
let transformed = await pluginContainer.transform(code, id, { ssr });
|
|
1279
|
-
let [, exports] = esModuleLexer(transformed.code);
|
|
1280
|
-
let exportNames = exports.map((e) => e.n);
|
|
1281
|
-
return exportNames;
|
|
1282
|
-
};
|
|
1283
|
-
var getServerBundleBuildConfig = (viteUserConfig) => {
|
|
1284
|
-
if (!("__reactRouterServerBundleBuildConfig" in viteUserConfig) || !viteUserConfig.__reactRouterServerBundleBuildConfig) {
|
|
1285
|
-
return null;
|
|
1286
|
-
}
|
|
1287
|
-
return viteUserConfig.__reactRouterServerBundleBuildConfig;
|
|
1288
|
-
};
|
|
1289
|
-
var getServerBuildDirectory = (ctx) => path4.join(
|
|
1290
|
-
ctx.reactRouterConfig.buildDirectory,
|
|
1291
|
-
"server",
|
|
1292
|
-
...ctx.serverBundleBuildConfig ? [ctx.serverBundleBuildConfig.serverBundleId] : []
|
|
1293
|
-
);
|
|
1294
|
-
var getClientBuildDirectory = (reactRouterConfig) => path4.join(reactRouterConfig.buildDirectory, "client");
|
|
1295
|
-
var defaultEntriesDir = path4.resolve(
|
|
1296
|
-
path4.dirname(require4.resolve("@react-router/dev/package.json")),
|
|
1297
|
-
"dist",
|
|
1298
|
-
"config",
|
|
1299
|
-
"defaults"
|
|
1300
|
-
);
|
|
1301
|
-
var defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path4.join(defaultEntriesDir, filename3));
|
|
1302
|
-
invariant(defaultEntries.length > 0, "No default entries found");
|
|
1303
|
-
var reactRouterDevLoadContext = () => ({});
|
|
1304
|
-
var reactRouterVitePlugin = () => {
|
|
1305
|
-
let rootDirectory;
|
|
1306
|
-
let viteCommand;
|
|
1307
|
-
let viteUserConfig;
|
|
1308
|
-
let viteConfigEnv;
|
|
1309
|
-
let viteConfig;
|
|
1310
|
-
let cssModulesManifest = {};
|
|
1311
|
-
let viteChildCompiler = null;
|
|
1312
|
-
let reactRouterConfigLoader;
|
|
1313
|
-
let typegenWatcherPromise;
|
|
1314
|
-
let logger;
|
|
1315
|
-
let firstLoad = true;
|
|
1316
|
-
let ctx;
|
|
1317
|
-
let updatePluginContext = async () => {
|
|
1318
|
-
let reactRouterConfig;
|
|
1319
|
-
let reactRouterConfigResult = await reactRouterConfigLoader.getConfig();
|
|
1320
|
-
if (reactRouterConfigResult.ok) {
|
|
1321
|
-
reactRouterConfig = reactRouterConfigResult.value;
|
|
1322
|
-
} else {
|
|
1323
|
-
logger.error(reactRouterConfigResult.error);
|
|
1324
|
-
if (firstLoad) {
|
|
1325
|
-
process.exit(1);
|
|
1326
|
-
}
|
|
1327
|
-
return;
|
|
1328
|
-
}
|
|
1329
|
-
let { entryClientFilePath, entryServerFilePath } = await resolveEntryFiles({
|
|
1330
|
-
rootDirectory,
|
|
1331
|
-
reactRouterConfig
|
|
1332
|
-
});
|
|
1333
|
-
let publicPath = viteUserConfig.base ?? "/";
|
|
1334
|
-
if (reactRouterConfig.basename !== "/" && viteCommand === "serve" && !viteUserConfig.server?.middlewareMode && !reactRouterConfig.basename.startsWith(publicPath)) {
|
|
1335
|
-
logger.error(
|
|
1336
|
-
colors2.red(
|
|
1337
|
-
"When using the React Router `basename` and the Vite `base` config, the `basename` config must begin with `base` for the default Vite dev server."
|
|
1338
|
-
)
|
|
1339
|
-
);
|
|
1340
|
-
process.exit(1);
|
|
1341
|
-
}
|
|
1342
|
-
let viteManifestEnabled = viteUserConfig.build?.manifest === true;
|
|
1343
|
-
let ssrBuildCtx = viteConfigEnv.isSsrBuild && viteCommand === "build" ? {
|
|
1344
|
-
isSsrBuild: true,
|
|
1345
|
-
getReactRouterServerManifest: async () => (await generateReactRouterManifestsForBuild()).reactRouterServerManifest,
|
|
1346
|
-
serverBundleBuildConfig: getServerBundleBuildConfig(viteUserConfig)
|
|
1347
|
-
} : { isSsrBuild: false };
|
|
1348
|
-
firstLoad = false;
|
|
1349
|
-
ctx = {
|
|
1350
|
-
reactRouterConfig,
|
|
1351
|
-
rootDirectory,
|
|
1352
|
-
entryClientFilePath,
|
|
1353
|
-
entryServerFilePath,
|
|
1354
|
-
publicPath,
|
|
1355
|
-
viteManifestEnabled,
|
|
1356
|
-
...ssrBuildCtx
|
|
1357
|
-
};
|
|
1358
|
-
};
|
|
1359
|
-
let pluginIndex = (pluginName) => {
|
|
1360
|
-
invariant(viteConfig);
|
|
1361
|
-
return viteConfig.plugins.findIndex((plugin2) => plugin2.name === pluginName);
|
|
1362
|
-
};
|
|
1363
|
-
let getServerEntry = async () => {
|
|
1364
|
-
invariant(viteConfig, "viteconfig required to generate the server entry");
|
|
1365
|
-
let routes = ctx.serverBundleBuildConfig ? (
|
|
1366
|
-
// For server bundle builds, the server build should only import the
|
|
1367
|
-
// routes for this bundle rather than importing all routes
|
|
1368
|
-
ctx.serverBundleBuildConfig.routes
|
|
1369
|
-
) : (
|
|
1370
|
-
// Otherwise, all routes are imported as usual
|
|
1371
|
-
ctx.reactRouterConfig.routes
|
|
1372
|
-
);
|
|
1373
|
-
return `
|
|
1374
|
-
import * as entryServer from ${JSON.stringify(
|
|
1375
|
-
resolveFileUrl(ctx, ctx.entryServerFilePath)
|
|
1376
|
-
)};
|
|
1377
|
-
${Object.keys(routes).map((key, index) => {
|
|
1378
|
-
let route = routes[key];
|
|
1379
|
-
return `import * as route${index} from ${JSON.stringify(
|
|
1380
|
-
resolveFileUrl(
|
|
1381
|
-
ctx,
|
|
1382
|
-
resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
1383
|
-
)
|
|
1384
|
-
)};`;
|
|
1385
|
-
}).join("\n")}
|
|
1386
|
-
export { default as assets } from ${JSON.stringify(
|
|
1387
|
-
virtual.serverManifest.id
|
|
1388
|
-
)};
|
|
1389
|
-
export const assetsBuildDirectory = ${JSON.stringify(
|
|
1390
|
-
path4.relative(
|
|
1391
|
-
ctx.rootDirectory,
|
|
1392
|
-
getClientBuildDirectory(ctx.reactRouterConfig)
|
|
1393
|
-
)
|
|
1394
|
-
)};
|
|
1395
|
-
export const basename = ${JSON.stringify(ctx.reactRouterConfig.basename)};
|
|
1396
|
-
export const future = ${JSON.stringify(ctx.reactRouterConfig.future)};
|
|
1397
|
-
export const isSpaMode = ${!ctx.reactRouterConfig.ssr && ctx.reactRouterConfig.prerender == null};
|
|
1398
|
-
export const publicPath = ${JSON.stringify(ctx.publicPath)};
|
|
1399
|
-
export const entry = { module: entryServer };
|
|
1400
|
-
export const routes = {
|
|
1401
|
-
${Object.keys(routes).map((key, index) => {
|
|
1402
|
-
let route = routes[key];
|
|
1403
|
-
return `${JSON.stringify(key)}: {
|
|
1404
|
-
id: ${JSON.stringify(route.id)},
|
|
1405
|
-
parentId: ${JSON.stringify(route.parentId)},
|
|
1406
|
-
path: ${JSON.stringify(route.path)},
|
|
1407
|
-
index: ${JSON.stringify(route.index)},
|
|
1408
|
-
caseSensitive: ${JSON.stringify(route.caseSensitive)},
|
|
1409
|
-
module: route${index}
|
|
1410
|
-
}`;
|
|
1411
|
-
}).join(",\n ")}
|
|
1412
|
-
};`;
|
|
1413
|
-
};
|
|
1414
|
-
let loadViteManifest = async (directory) => {
|
|
1415
|
-
let manifestContents = await fse.readFile(
|
|
1416
|
-
path4.resolve(directory, ".vite", "manifest.json"),
|
|
1417
|
-
"utf-8"
|
|
1418
|
-
);
|
|
1419
|
-
return JSON.parse(manifestContents);
|
|
1420
|
-
};
|
|
1421
|
-
let hasDependency = (name) => {
|
|
1422
|
-
try {
|
|
1423
|
-
return Boolean(require4.resolve(name, { paths: [ctx.rootDirectory] }));
|
|
1424
|
-
} catch (err2) {
|
|
1425
|
-
return false;
|
|
1426
|
-
}
|
|
1427
|
-
};
|
|
1428
|
-
let getViteManifestAssetPaths = (viteManifest) => {
|
|
1429
|
-
let cssUrlPaths = Object.values(viteManifest).filter((chunk) => chunk.file.endsWith(".css")).map((chunk) => chunk.file);
|
|
1430
|
-
let chunkAssetPaths = Object.values(viteManifest).flatMap(
|
|
1431
|
-
(chunk) => chunk.assets ?? []
|
|
1432
|
-
);
|
|
1433
|
-
return /* @__PURE__ */ new Set([...cssUrlPaths, ...chunkAssetPaths]);
|
|
1434
|
-
};
|
|
1435
|
-
let generateReactRouterManifestsForBuild = async () => {
|
|
1436
|
-
invariant(viteConfig);
|
|
1437
|
-
let viteManifest = await loadViteManifest(
|
|
1438
|
-
getClientBuildDirectory(ctx.reactRouterConfig)
|
|
1439
|
-
);
|
|
1440
|
-
let entry = getReactRouterManifestBuildAssets(
|
|
1441
|
-
ctx,
|
|
1442
|
-
viteManifest,
|
|
1443
|
-
ctx.entryClientFilePath
|
|
1444
|
-
);
|
|
1445
|
-
let browserRoutes = {};
|
|
1446
|
-
let serverRoutes = {};
|
|
1447
|
-
let routeManifestExports = await getRouteManifestModuleExports(
|
|
1448
|
-
viteChildCompiler,
|
|
1449
|
-
ctx
|
|
1450
|
-
);
|
|
1451
|
-
for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
|
|
1452
|
-
let routeFilePath = path4.join(
|
|
1453
|
-
ctx.reactRouterConfig.appDirectory,
|
|
1454
|
-
route.file
|
|
1455
|
-
);
|
|
1456
|
-
let sourceExports = routeManifestExports[key];
|
|
1457
|
-
let isRootRoute = route.parentId === void 0;
|
|
1458
|
-
let routeManifestEntry = {
|
|
1459
|
-
id: route.id,
|
|
1460
|
-
parentId: route.parentId,
|
|
1461
|
-
path: route.path,
|
|
1462
|
-
index: route.index,
|
|
1463
|
-
caseSensitive: route.caseSensitive,
|
|
1464
|
-
hasAction: sourceExports.includes("action"),
|
|
1465
|
-
hasLoader: sourceExports.includes("loader"),
|
|
1466
|
-
hasClientAction: sourceExports.includes("clientAction"),
|
|
1467
|
-
hasClientLoader: sourceExports.includes("clientLoader"),
|
|
1468
|
-
hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
|
|
1469
|
-
...getReactRouterManifestBuildAssets(
|
|
1470
|
-
ctx,
|
|
1471
|
-
viteManifest,
|
|
1472
|
-
routeFilePath,
|
|
1473
|
-
// If this is the root route, we also need to include assets from the
|
|
1474
|
-
// client entry file as this is a common way for consumers to import
|
|
1475
|
-
// global reset styles, etc.
|
|
1476
|
-
isRootRoute ? [ctx.entryClientFilePath] : []
|
|
1477
|
-
)
|
|
1478
|
-
};
|
|
1479
|
-
browserRoutes[key] = routeManifestEntry;
|
|
1480
|
-
let serverBundleRoutes = ctx.serverBundleBuildConfig?.routes;
|
|
1481
|
-
if (!serverBundleRoutes || serverBundleRoutes[key]) {
|
|
1482
|
-
serverRoutes[key] = routeManifestEntry;
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
let fingerprintedValues = { entry, routes: browserRoutes };
|
|
1486
|
-
let version = getHash(JSON.stringify(fingerprintedValues), 8);
|
|
1487
|
-
let manifestPath = path4.posix.join(
|
|
1488
|
-
viteConfig.build.assetsDir,
|
|
1489
|
-
`manifest-${version}.js`
|
|
1490
|
-
);
|
|
1491
|
-
let url2 = `${ctx.publicPath}${manifestPath}`;
|
|
1492
|
-
let nonFingerprintedValues = { url: url2, version };
|
|
1493
|
-
let reactRouterBrowserManifest = {
|
|
1494
|
-
...fingerprintedValues,
|
|
1495
|
-
...nonFingerprintedValues
|
|
1496
|
-
};
|
|
1497
|
-
await writeFileSafe(
|
|
1498
|
-
path4.join(getClientBuildDirectory(ctx.reactRouterConfig), manifestPath),
|
|
1499
|
-
`window.__reactRouterManifest=${JSON.stringify(
|
|
1500
|
-
reactRouterBrowserManifest
|
|
1501
|
-
)};`
|
|
1502
|
-
);
|
|
1503
|
-
let reactRouterServerManifest = {
|
|
1504
|
-
...reactRouterBrowserManifest,
|
|
1505
|
-
routes: serverRoutes
|
|
1506
|
-
};
|
|
1507
|
-
return {
|
|
1508
|
-
reactRouterBrowserManifest,
|
|
1509
|
-
reactRouterServerManifest
|
|
1510
|
-
};
|
|
1511
|
-
};
|
|
1512
|
-
let getReactRouterManifestForDev = async () => {
|
|
1513
|
-
let routes = {};
|
|
1514
|
-
let routeManifestExports = await getRouteManifestModuleExports(
|
|
1515
|
-
viteChildCompiler,
|
|
1516
|
-
ctx
|
|
1517
|
-
);
|
|
1518
|
-
for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
|
|
1519
|
-
let sourceExports = routeManifestExports[key];
|
|
1520
|
-
routes[key] = {
|
|
1521
|
-
id: route.id,
|
|
1522
|
-
parentId: route.parentId,
|
|
1523
|
-
path: route.path,
|
|
1524
|
-
index: route.index,
|
|
1525
|
-
caseSensitive: route.caseSensitive,
|
|
1526
|
-
module: combineURLs(
|
|
1527
|
-
ctx.publicPath,
|
|
1528
|
-
resolveFileUrl(
|
|
1529
|
-
ctx,
|
|
1530
|
-
resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
1531
|
-
)
|
|
1532
|
-
),
|
|
1533
|
-
hasAction: sourceExports.includes("action"),
|
|
1534
|
-
hasLoader: sourceExports.includes("loader"),
|
|
1535
|
-
hasClientAction: sourceExports.includes("clientAction"),
|
|
1536
|
-
hasClientLoader: sourceExports.includes("clientLoader"),
|
|
1537
|
-
hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
|
|
1538
|
-
imports: []
|
|
1539
|
-
};
|
|
1540
|
-
}
|
|
1541
|
-
return {
|
|
1542
|
-
version: String(Math.random()),
|
|
1543
|
-
url: combineURLs(ctx.publicPath, virtual.browserManifest.url),
|
|
1544
|
-
hmr: {
|
|
1545
|
-
runtime: combineURLs(ctx.publicPath, virtualInjectHmrRuntime.url)
|
|
1546
|
-
},
|
|
1547
|
-
entry: {
|
|
1548
|
-
module: combineURLs(
|
|
1549
|
-
ctx.publicPath,
|
|
1550
|
-
resolveFileUrl(ctx, ctx.entryClientFilePath)
|
|
1551
|
-
),
|
|
1552
|
-
imports: []
|
|
1553
|
-
},
|
|
1554
|
-
routes
|
|
1555
|
-
};
|
|
1556
|
-
};
|
|
1557
|
-
return [
|
|
1558
|
-
{
|
|
1559
|
-
name: "react-router",
|
|
1560
|
-
config: async (_viteUserConfig, _viteConfigEnv) => {
|
|
1561
|
-
await preloadVite();
|
|
1562
|
-
let vite = getVite();
|
|
1563
|
-
viteUserConfig = _viteUserConfig;
|
|
1564
|
-
viteConfigEnv = _viteConfigEnv;
|
|
1565
|
-
viteCommand = viteConfigEnv.command;
|
|
1566
|
-
let viteClientConditions = [
|
|
1567
|
-
...vite.defaultClientConditions ?? []
|
|
1568
|
-
];
|
|
1569
|
-
let moduleSyncEnabled = require4("#module-sync-enabled").default;
|
|
1570
|
-
let viteServerConditions = [
|
|
1571
|
-
...vite.defaultServerConditions ?? [],
|
|
1572
|
-
...moduleSyncEnabled ? ["module-sync"] : []
|
|
1573
|
-
];
|
|
1574
|
-
logger = vite.createLogger(viteUserConfig.logLevel, {
|
|
1575
|
-
prefix: "[react-router]"
|
|
1576
|
-
});
|
|
1577
|
-
rootDirectory = viteUserConfig.root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
|
|
1578
|
-
if (viteCommand === "serve") {
|
|
1579
|
-
typegenWatcherPromise = watch(rootDirectory, {
|
|
1580
|
-
// ignore `info` logs from typegen since they are redundant when Vite plugin logs are active
|
|
1581
|
-
logger: vite.createLogger("warn", { prefix: "[react-router]" })
|
|
1582
|
-
});
|
|
1583
|
-
}
|
|
1584
|
-
reactRouterConfigLoader = await createConfigLoader({
|
|
1585
|
-
rootDirectory,
|
|
1586
|
-
watch: viteCommand === "serve"
|
|
1587
|
-
});
|
|
1588
|
-
await updatePluginContext();
|
|
1589
|
-
Object.assign(
|
|
1590
|
-
process.env,
|
|
1591
|
-
vite.loadEnv(
|
|
1592
|
-
viteConfigEnv.mode,
|
|
1593
|
-
ctx.rootDirectory,
|
|
1594
|
-
// We override default prefix of "VITE_" with a blank string since
|
|
1595
|
-
// we're targeting the server, so we want to load all environment
|
|
1596
|
-
// variables, not just those explicitly marked for the client
|
|
1597
|
-
""
|
|
1598
|
-
)
|
|
1599
|
-
);
|
|
1600
|
-
let baseRollupOptions = {
|
|
1601
|
-
// Silence Rollup "use client" warnings
|
|
1602
|
-
// Adapted from https://github.com/vitejs/vite-plugin-react/pull/144
|
|
1603
|
-
onwarn(warning, defaultHandler) {
|
|
1604
|
-
if (warning.code === "MODULE_LEVEL_DIRECTIVE" && warning.message.includes("use client")) {
|
|
1605
|
-
return;
|
|
1606
|
-
}
|
|
1607
|
-
if (viteUserConfig.build?.rollupOptions?.onwarn) {
|
|
1608
|
-
viteUserConfig.build.rollupOptions.onwarn(
|
|
1609
|
-
warning,
|
|
1610
|
-
defaultHandler
|
|
1611
|
-
);
|
|
1612
|
-
} else {
|
|
1613
|
-
defaultHandler(warning);
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
};
|
|
1617
|
-
return {
|
|
1618
|
-
__reactRouterPluginContext: ctx,
|
|
1619
|
-
appType: viteCommand === "serve" && viteConfigEnv.mode === "production" && ctx.reactRouterConfig.ssr === false ? "spa" : "custom",
|
|
1620
|
-
ssr: {
|
|
1621
|
-
external: ssrExternals,
|
|
1622
|
-
resolve: {
|
|
1623
|
-
conditions: viteCommand === "build" ? viteServerConditions : ["development", ...viteServerConditions],
|
|
1624
|
-
externalConditions: viteCommand === "build" ? viteServerConditions : ["development", ...viteServerConditions]
|
|
1625
|
-
}
|
|
1626
|
-
},
|
|
1627
|
-
optimizeDeps: {
|
|
1628
|
-
entries: ctx.reactRouterConfig.future.unstable_optimizeDeps ? [
|
|
1629
|
-
ctx.entryClientFilePath,
|
|
1630
|
-
...Object.values(ctx.reactRouterConfig.routes).map(
|
|
1631
|
-
(route) => path4.join(ctx.reactRouterConfig.appDirectory, route.file)
|
|
1632
|
-
)
|
|
1633
|
-
] : [],
|
|
1634
|
-
include: [
|
|
1635
|
-
// Pre-bundle React dependencies to avoid React duplicates,
|
|
1636
|
-
// even if React dependencies are not direct dependencies.
|
|
1637
|
-
// https://react.dev/warnings/invalid-hook-call-warning#duplicate-react
|
|
1638
|
-
"react",
|
|
1639
|
-
"react/jsx-runtime",
|
|
1640
|
-
"react/jsx-dev-runtime",
|
|
1641
|
-
"react-dom",
|
|
1642
|
-
"react-dom/client",
|
|
1643
|
-
// Pre-bundle router dependencies to avoid router duplicates.
|
|
1644
|
-
// Mismatching routers cause `Error: You must render this element inside a <Remix> element`.
|
|
1645
|
-
"react-router",
|
|
1646
|
-
"react-router/dom",
|
|
1647
|
-
// Check to avoid "Failed to resolve dependency: react-router-dom, present in 'optimizeDeps.include'"
|
|
1648
|
-
...hasDependency("react-router-dom") ? ["react-router-dom"] : []
|
|
1649
|
-
]
|
|
1650
|
-
},
|
|
1651
|
-
esbuild: {
|
|
1652
|
-
jsx: "automatic",
|
|
1653
|
-
jsxDev: viteCommand !== "build"
|
|
1654
|
-
},
|
|
1655
|
-
resolve: {
|
|
1656
|
-
dedupe: [
|
|
1657
|
-
// https://react.dev/warnings/invalid-hook-call-warning#duplicate-react
|
|
1658
|
-
"react",
|
|
1659
|
-
"react-dom",
|
|
1660
|
-
// see description for `optimizeDeps.include`
|
|
1661
|
-
"react-router",
|
|
1662
|
-
"react-router/dom",
|
|
1663
|
-
"react-router-dom"
|
|
1664
|
-
],
|
|
1665
|
-
conditions: viteCommand === "build" ? viteClientConditions : ["development", ...viteClientConditions]
|
|
1666
|
-
},
|
|
1667
|
-
base: viteUserConfig.base,
|
|
1668
|
-
// When consumer provides an allow list for files that can be read by
|
|
1669
|
-
// the server, ensure that the default entry files are included.
|
|
1670
|
-
// If we don't do this and a default entry file is used, the server
|
|
1671
|
-
// will throw an error that the file is not allowed to be read.
|
|
1672
|
-
// https://vitejs.dev/config/server-options#server-fs-allow
|
|
1673
|
-
server: viteUserConfig.server?.fs?.allow ? { fs: { allow: defaultEntries } } : void 0,
|
|
1674
|
-
// Vite config options for building
|
|
1675
|
-
...viteCommand === "build" ? {
|
|
1676
|
-
build: {
|
|
1677
|
-
cssMinify: viteUserConfig.build?.cssMinify ?? true,
|
|
1678
|
-
...!viteConfigEnv.isSsrBuild ? {
|
|
1679
|
-
manifest: true,
|
|
1680
|
-
outDir: getClientBuildDirectory(ctx.reactRouterConfig),
|
|
1681
|
-
rollupOptions: {
|
|
1682
|
-
...baseRollupOptions,
|
|
1683
|
-
preserveEntrySignatures: "exports-only",
|
|
1684
|
-
input: [
|
|
1685
|
-
ctx.entryClientFilePath,
|
|
1686
|
-
...Object.values(ctx.reactRouterConfig.routes).map(
|
|
1687
|
-
(route) => `${path4.resolve(
|
|
1688
|
-
ctx.reactRouterConfig.appDirectory,
|
|
1689
|
-
route.file
|
|
1690
|
-
)}${BUILD_CLIENT_ROUTE_QUERY_STRING}`
|
|
1691
|
-
)
|
|
1692
|
-
]
|
|
1693
|
-
}
|
|
1694
|
-
} : {
|
|
1695
|
-
// We move SSR-only assets to client assets. Note that the
|
|
1696
|
-
// SSR build can also emit code-split JS files (e.g. by
|
|
1697
|
-
// dynamic import) under the same assets directory
|
|
1698
|
-
// regardless of "ssrEmitAssets" option, so we also need to
|
|
1699
|
-
// keep these JS files have to be kept as-is.
|
|
1700
|
-
ssrEmitAssets: true,
|
|
1701
|
-
copyPublicDir: false,
|
|
1702
|
-
// Assets in the public directory are only used by the client
|
|
1703
|
-
manifest: true,
|
|
1704
|
-
// We need the manifest to detect SSR-only assets
|
|
1705
|
-
outDir: getServerBuildDirectory(ctx),
|
|
1706
|
-
rollupOptions: {
|
|
1707
|
-
...baseRollupOptions,
|
|
1708
|
-
preserveEntrySignatures: "exports-only",
|
|
1709
|
-
input: viteUserConfig.build?.rollupOptions?.input ?? virtual.serverBuild.id,
|
|
1710
|
-
output: {
|
|
1711
|
-
entryFileNames: ctx.reactRouterConfig.serverBuildFile,
|
|
1712
|
-
format: ctx.reactRouterConfig.serverModuleFormat
|
|
1713
|
-
}
|
|
1714
|
-
}
|
|
1715
|
-
}
|
|
1716
|
-
}
|
|
1717
|
-
} : void 0,
|
|
1718
|
-
// Vite config options for SPA preview mode
|
|
1719
|
-
...viteCommand === "serve" && ctx.reactRouterConfig.ssr === false ? {
|
|
1720
|
-
build: {
|
|
1721
|
-
manifest: true,
|
|
1722
|
-
outDir: getClientBuildDirectory(ctx.reactRouterConfig)
|
|
1723
|
-
}
|
|
1724
|
-
} : void 0
|
|
1725
|
-
};
|
|
1726
|
-
},
|
|
1727
|
-
async configResolved(resolvedViteConfig) {
|
|
1728
|
-
await initEsModuleLexer;
|
|
1729
|
-
viteConfig = resolvedViteConfig;
|
|
1730
|
-
invariant(viteConfig);
|
|
1731
|
-
if (!viteConfig.configFile) {
|
|
1732
|
-
throw new Error(
|
|
1733
|
-
"The React Router Vite plugin requires the use of a Vite config file"
|
|
1734
|
-
);
|
|
1735
|
-
}
|
|
1736
|
-
let vite = getVite();
|
|
1737
|
-
let childCompilerConfigFile = await vite.loadConfigFromFile(
|
|
1738
|
-
{
|
|
1739
|
-
command: viteConfig.command,
|
|
1740
|
-
mode: viteConfig.mode,
|
|
1741
|
-
isSsrBuild: ctx.isSsrBuild
|
|
1742
|
-
},
|
|
1743
|
-
viteConfig.configFile
|
|
1744
|
-
);
|
|
1745
|
-
invariant(
|
|
1746
|
-
childCompilerConfigFile,
|
|
1747
|
-
"Vite config file was unable to be resolved for React Router child compiler"
|
|
1748
|
-
);
|
|
1749
|
-
let rollupPrePlugins = [
|
|
1750
|
-
{ pluginName: "@mdx-js/rollup", displayName: "@mdx-js/rollup" }
|
|
1751
|
-
];
|
|
1752
|
-
for (let prePlugin of rollupPrePlugins) {
|
|
1753
|
-
let prePluginIndex = pluginIndex(prePlugin.pluginName);
|
|
1754
|
-
if (prePluginIndex >= 0 && prePluginIndex > pluginIndex("react-router")) {
|
|
1755
|
-
throw new Error(
|
|
1756
|
-
`The "${prePlugin.displayName}" plugin should be placed before the React Router plugin in your Vite config file`
|
|
1757
|
-
);
|
|
1758
|
-
}
|
|
1759
|
-
}
|
|
1760
|
-
viteChildCompiler = await vite.createServer({
|
|
1761
|
-
...viteUserConfig,
|
|
1762
|
-
mode: viteConfig.mode,
|
|
1763
|
-
server: {
|
|
1764
|
-
watch: viteConfig.command === "build" ? null : void 0,
|
|
1765
|
-
preTransformRequests: false,
|
|
1766
|
-
hmr: false
|
|
1767
|
-
},
|
|
1768
|
-
configFile: false,
|
|
1769
|
-
envFile: false,
|
|
1770
|
-
plugins: [
|
|
1771
|
-
...(childCompilerConfigFile.config.plugins ?? []).flat().filter(
|
|
1772
|
-
(plugin2) => typeof plugin2 === "object" && plugin2 !== null && "name" in plugin2 && plugin2.name !== "react-router" && plugin2.name !== "react-router:route-exports" && plugin2.name !== "react-router:hmr-updates"
|
|
1773
|
-
)
|
|
1774
|
-
]
|
|
1775
|
-
});
|
|
1776
|
-
await viteChildCompiler.pluginContainer.buildStart({});
|
|
1777
|
-
},
|
|
1778
|
-
async transform(code, id) {
|
|
1779
|
-
if (isCssModulesFile(id)) {
|
|
1780
|
-
cssModulesManifest[id] = code;
|
|
1781
|
-
}
|
|
1782
|
-
},
|
|
1783
|
-
buildStart() {
|
|
1784
|
-
invariant(viteConfig);
|
|
1785
|
-
if (viteCommand === "build" && viteConfig.mode === "production" && !viteConfig.build.ssr && viteConfig.build.sourcemap) {
|
|
1786
|
-
viteConfig.logger.warn(
|
|
1787
|
-
colors2.yellow(
|
|
1788
|
-
"\n" + colors2.bold(" \u26A0\uFE0F Source maps are enabled in production\n") + [
|
|
1789
|
-
"This makes your server code publicly",
|
|
1790
|
-
"visible in the browser. This is highly",
|
|
1791
|
-
"discouraged! If you insist, ensure that",
|
|
1792
|
-
"you are using environment variables for",
|
|
1793
|
-
"secrets and not hard-coding them in",
|
|
1794
|
-
"your source code."
|
|
1795
|
-
].map((line) => " " + line).join("\n") + "\n"
|
|
1796
|
-
)
|
|
1797
|
-
);
|
|
1798
|
-
}
|
|
1799
|
-
},
|
|
1800
|
-
async configureServer(viteDevServer) {
|
|
1801
|
-
setDevServerHooks({
|
|
1802
|
-
// Give the request handler access to the critical CSS in dev to avoid a
|
|
1803
|
-
// flash of unstyled content since Vite injects CSS file contents via JS
|
|
1804
|
-
getCriticalCss: async (build, url2) => {
|
|
1805
|
-
return getStylesForUrl({
|
|
1806
|
-
rootDirectory: ctx.rootDirectory,
|
|
1807
|
-
entryClientFilePath: ctx.entryClientFilePath,
|
|
1808
|
-
reactRouterConfig: ctx.reactRouterConfig,
|
|
1809
|
-
viteDevServer,
|
|
1810
|
-
cssModulesManifest,
|
|
1811
|
-
build,
|
|
1812
|
-
url: url2
|
|
1813
|
-
});
|
|
1814
|
-
},
|
|
1815
|
-
// If an error is caught within the request handler, let Vite fix the
|
|
1816
|
-
// stack trace so it maps back to the actual source code
|
|
1817
|
-
processRequestError: (error) => {
|
|
1818
|
-
if (error instanceof Error) {
|
|
1819
|
-
viteDevServer.ssrFixStacktrace(error);
|
|
1820
|
-
}
|
|
1821
|
-
}
|
|
1822
|
-
});
|
|
1823
|
-
reactRouterConfigLoader.onChange(
|
|
1824
|
-
async ({
|
|
1825
|
-
result,
|
|
1826
|
-
configCodeUpdated,
|
|
1827
|
-
configChanged,
|
|
1828
|
-
routeConfigChanged
|
|
1829
|
-
}) => {
|
|
1830
|
-
if (!result.ok) {
|
|
1831
|
-
invalidateVirtualModules(viteDevServer);
|
|
1832
|
-
logger.error(result.error, {
|
|
1833
|
-
clear: true,
|
|
1834
|
-
timestamp: true
|
|
1835
|
-
});
|
|
1836
|
-
return;
|
|
1837
|
-
}
|
|
1838
|
-
if (routeConfigChanged) {
|
|
1839
|
-
logger.info(colors2.green("Route config changed."), {
|
|
1840
|
-
clear: true,
|
|
1841
|
-
timestamp: true
|
|
1842
|
-
});
|
|
1843
|
-
} else if (configCodeUpdated) {
|
|
1844
|
-
logger.info(colors2.green("Config updated."), {
|
|
1845
|
-
clear: true,
|
|
1846
|
-
timestamp: true
|
|
1847
|
-
});
|
|
1848
|
-
}
|
|
1849
|
-
await updatePluginContext();
|
|
1850
|
-
if (configChanged) {
|
|
1851
|
-
invalidateVirtualModules(viteDevServer);
|
|
1852
|
-
}
|
|
1853
|
-
}
|
|
1854
|
-
);
|
|
1855
|
-
return () => {
|
|
1856
|
-
if (!viteDevServer.config.server.middlewareMode) {
|
|
1857
|
-
viteDevServer.middlewares.use(async (req, res, next) => {
|
|
1858
|
-
try {
|
|
1859
|
-
let build = await viteDevServer.ssrLoadModule(
|
|
1860
|
-
virtual.serverBuild.id
|
|
1861
|
-
);
|
|
1862
|
-
let handler = createRequestHandler(build, "development");
|
|
1863
|
-
let nodeHandler = async (nodeReq, nodeRes) => {
|
|
1864
|
-
let req2 = fromNodeRequest(nodeReq, nodeRes);
|
|
1865
|
-
let res2 = await handler(
|
|
1866
|
-
req2,
|
|
1867
|
-
await reactRouterDevLoadContext(req2)
|
|
1868
|
-
);
|
|
1869
|
-
await toNodeRequest(res2, nodeRes);
|
|
1870
|
-
};
|
|
1871
|
-
await nodeHandler(req, res);
|
|
1872
|
-
} catch (error) {
|
|
1873
|
-
next(error);
|
|
1874
|
-
}
|
|
1875
|
-
});
|
|
1876
|
-
}
|
|
1877
|
-
};
|
|
1878
|
-
},
|
|
1879
|
-
writeBundle: {
|
|
1880
|
-
// After the SSR build is finished, we inspect the Vite manifest for
|
|
1881
|
-
// the SSR build and move server-only assets to client assets directory
|
|
1882
|
-
async handler() {
|
|
1883
|
-
if (!ctx.isSsrBuild) {
|
|
1884
|
-
return;
|
|
1885
|
-
}
|
|
1886
|
-
invariant(viteConfig);
|
|
1887
|
-
let clientBuildDirectory = getClientBuildDirectory(
|
|
1888
|
-
ctx.reactRouterConfig
|
|
1889
|
-
);
|
|
1890
|
-
let serverBuildDirectory = getServerBuildDirectory(ctx);
|
|
1891
|
-
let ssrViteManifest = await loadViteManifest(serverBuildDirectory);
|
|
1892
|
-
let ssrAssetPaths = getViteManifestAssetPaths(ssrViteManifest);
|
|
1893
|
-
let movedAssetPaths = [];
|
|
1894
|
-
for (let ssrAssetPath of ssrAssetPaths) {
|
|
1895
|
-
let src = path4.join(serverBuildDirectory, ssrAssetPath);
|
|
1896
|
-
let dest = path4.join(clientBuildDirectory, ssrAssetPath);
|
|
1897
|
-
if (!fse.existsSync(dest)) {
|
|
1898
|
-
await fse.move(src, dest);
|
|
1899
|
-
movedAssetPaths.push(dest);
|
|
1900
|
-
} else {
|
|
1901
|
-
await fse.remove(src);
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
let ssrCssPaths = Object.values(ssrViteManifest).flatMap(
|
|
1905
|
-
(chunk) => chunk.css ?? []
|
|
1906
|
-
);
|
|
1907
|
-
await Promise.all(
|
|
1908
|
-
ssrCssPaths.map(
|
|
1909
|
-
(cssPath) => fse.remove(path4.join(serverBuildDirectory, cssPath))
|
|
1910
|
-
)
|
|
1911
|
-
);
|
|
1912
|
-
if (movedAssetPaths.length) {
|
|
1913
|
-
viteConfig.logger.info(
|
|
1914
|
-
[
|
|
1915
|
-
"",
|
|
1916
|
-
`${colors2.green("\u2713")} ${movedAssetPaths.length} asset${movedAssetPaths.length > 1 ? "s" : ""} moved from React Router server build to client assets.`,
|
|
1917
|
-
...movedAssetPaths.map(
|
|
1918
|
-
(movedAssetPath) => colors2.dim(path4.relative(ctx.rootDirectory, movedAssetPath))
|
|
1919
|
-
),
|
|
1920
|
-
""
|
|
1921
|
-
].join("\n")
|
|
1922
|
-
);
|
|
1923
|
-
}
|
|
1924
|
-
if (ctx.reactRouterConfig.prerender != null && ctx.reactRouterConfig.prerender !== false) {
|
|
1925
|
-
await handlePrerender(
|
|
1926
|
-
viteConfig,
|
|
1927
|
-
ctx.reactRouterConfig,
|
|
1928
|
-
serverBuildDirectory,
|
|
1929
|
-
clientBuildDirectory
|
|
1930
|
-
);
|
|
1931
|
-
}
|
|
1932
|
-
if (!ctx.reactRouterConfig.ssr) {
|
|
1933
|
-
await handleSpaMode(
|
|
1934
|
-
viteConfig,
|
|
1935
|
-
ctx.reactRouterConfig,
|
|
1936
|
-
serverBuildDirectory,
|
|
1937
|
-
clientBuildDirectory
|
|
1938
|
-
);
|
|
1939
|
-
}
|
|
1940
|
-
if (!ctx.reactRouterConfig.ssr) {
|
|
1941
|
-
viteConfig.logger.info(
|
|
1942
|
-
[
|
|
1943
|
-
"Removing the server build in",
|
|
1944
|
-
colors2.green(serverBuildDirectory),
|
|
1945
|
-
"due to ssr:false"
|
|
1946
|
-
].join(" ")
|
|
1947
|
-
);
|
|
1948
|
-
fse.removeSync(serverBuildDirectory);
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
},
|
|
1952
|
-
async buildEnd() {
|
|
1953
|
-
await viteChildCompiler?.close();
|
|
1954
|
-
await reactRouterConfigLoader.close();
|
|
1955
|
-
let typegenWatcher = await typegenWatcherPromise;
|
|
1956
|
-
await typegenWatcher?.close();
|
|
1957
|
-
}
|
|
1958
|
-
},
|
|
1959
|
-
{
|
|
1960
|
-
name: "react-router:build-client-route",
|
|
1961
|
-
enforce: "pre",
|
|
1962
|
-
async transform(_code, id, options) {
|
|
1963
|
-
if (!id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING)) return;
|
|
1964
|
-
let routeModuleId = id.replace(BUILD_CLIENT_ROUTE_QUERY_STRING, "");
|
|
1965
|
-
let routeFileName = path4.basename(routeModuleId);
|
|
1966
|
-
let sourceExports = await getRouteModuleExports(
|
|
1967
|
-
viteChildCompiler,
|
|
1968
|
-
ctx,
|
|
1969
|
-
routeModuleId
|
|
1970
|
-
);
|
|
1971
|
-
let reexports = sourceExports.filter(
|
|
1972
|
-
(exportName) => options?.ssr && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS.includes(exportName)
|
|
1973
|
-
).join(", ");
|
|
1974
|
-
return `export { ${reexports} } from "./${routeFileName}";`;
|
|
1975
|
-
}
|
|
1976
|
-
},
|
|
1977
|
-
{
|
|
1978
|
-
name: "react-router:virtual-modules",
|
|
1979
|
-
enforce: "pre",
|
|
1980
|
-
resolveId(id) {
|
|
1981
|
-
const vmod2 = Object.values(virtual).find((vmod3) => vmod3.id === id);
|
|
1982
|
-
if (vmod2) return vmod2.resolvedId;
|
|
1983
|
-
},
|
|
1984
|
-
async load(id) {
|
|
1985
|
-
switch (id) {
|
|
1986
|
-
case virtual.serverBuild.resolvedId: {
|
|
1987
|
-
return await getServerEntry();
|
|
1988
|
-
}
|
|
1989
|
-
case virtual.serverManifest.resolvedId: {
|
|
1990
|
-
let reactRouterManifest = ctx.isSsrBuild ? await ctx.getReactRouterServerManifest() : await getReactRouterManifestForDev();
|
|
1991
|
-
return `export default ${jsesc(reactRouterManifest, {
|
|
1992
|
-
es6: true
|
|
1993
|
-
})};`;
|
|
1994
|
-
}
|
|
1995
|
-
case virtual.browserManifest.resolvedId: {
|
|
1996
|
-
if (viteCommand === "build") {
|
|
1997
|
-
throw new Error("This module only exists in development");
|
|
1998
|
-
}
|
|
1999
|
-
let reactRouterManifest = await getReactRouterManifestForDev();
|
|
2000
|
-
let reactRouterManifestString = jsesc(reactRouterManifest, {
|
|
2001
|
-
es6: true
|
|
2002
|
-
});
|
|
2003
|
-
return `window.__reactRouterManifest=${reactRouterManifestString};`;
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
},
|
|
2008
|
-
{
|
|
2009
|
-
name: "react-router:dot-server",
|
|
2010
|
-
enforce: "pre",
|
|
2011
|
-
async resolveId(id, importer, options) {
|
|
2012
|
-
let isOptimizeDeps = viteCommand === "serve" && options?.scan === true;
|
|
2013
|
-
if (isOptimizeDeps || options?.ssr) return;
|
|
2014
|
-
let isResolving = options?.custom?.["react-router:dot-server"] ?? false;
|
|
2015
|
-
if (isResolving) return;
|
|
2016
|
-
options.custom = { ...options.custom, "react-router:dot-server": true };
|
|
2017
|
-
let resolved = await this.resolve(id, importer, options);
|
|
2018
|
-
if (!resolved) return;
|
|
2019
|
-
let serverFileRE = /\.server(\.[cm]?[jt]sx?)?$/;
|
|
2020
|
-
let serverDirRE = /\/\.server\//;
|
|
2021
|
-
let isDotServer = serverFileRE.test(resolved.id) || serverDirRE.test(resolved.id);
|
|
2022
|
-
if (!isDotServer) return;
|
|
2023
|
-
if (!importer) return;
|
|
2024
|
-
if (viteCommand !== "build" && importer.endsWith(".html")) {
|
|
2025
|
-
return;
|
|
2026
|
-
}
|
|
2027
|
-
let vite = getVite();
|
|
2028
|
-
let importerShort = vite.normalizePath(
|
|
2029
|
-
path4.relative(ctx.rootDirectory, importer)
|
|
2030
|
-
);
|
|
2031
|
-
let isRoute = getRoute(ctx.reactRouterConfig, importer);
|
|
2032
|
-
if (isRoute) {
|
|
2033
|
-
let serverOnlyExports = SERVER_ONLY_ROUTE_EXPORTS.map(
|
|
2034
|
-
(xport) => `\`${xport}\``
|
|
2035
|
-
).join(", ");
|
|
2036
|
-
throw Error(
|
|
2037
|
-
[
|
|
2038
|
-
colors2.red(`Server-only module referenced by client`),
|
|
2039
|
-
"",
|
|
2040
|
-
` '${id}' imported by route '${importerShort}'`,
|
|
2041
|
-
"",
|
|
2042
|
-
` React Router automatically removes server-code from these exports:`,
|
|
2043
|
-
` ${serverOnlyExports}`,
|
|
2044
|
-
"",
|
|
2045
|
-
` But other route exports in '${importerShort}' depend on '${id}'.`,
|
|
2046
|
-
"",
|
|
2047
|
-
" See https://remix.run/docs/en/main/guides/vite#splitting-up-client-and-server-code",
|
|
2048
|
-
""
|
|
2049
|
-
].join("\n")
|
|
2050
|
-
);
|
|
2051
|
-
}
|
|
2052
|
-
throw Error(
|
|
2053
|
-
[
|
|
2054
|
-
colors2.red(`Server-only module referenced by client`),
|
|
2055
|
-
"",
|
|
2056
|
-
` '${id}' imported by '${importerShort}'`,
|
|
2057
|
-
"",
|
|
2058
|
-
" See https://remix.run/docs/en/main/guides/vite#splitting-up-client-and-server-code",
|
|
2059
|
-
""
|
|
2060
|
-
].join("\n")
|
|
2061
|
-
);
|
|
2062
|
-
}
|
|
2063
|
-
},
|
|
2064
|
-
{
|
|
2065
|
-
name: "react-router:dot-client",
|
|
2066
|
-
async transform(code, id, options) {
|
|
2067
|
-
if (!options?.ssr) return;
|
|
2068
|
-
let clientFileRE = /\.client(\.[cm]?[jt]sx?)?$/;
|
|
2069
|
-
let clientDirRE = /\/\.client\//;
|
|
2070
|
-
if (clientFileRE.test(id) || clientDirRE.test(id)) {
|
|
2071
|
-
let exports = esModuleLexer(code)[1];
|
|
2072
|
-
return {
|
|
2073
|
-
code: exports.map(
|
|
2074
|
-
({ n: name }) => name === "default" ? "export default undefined;" : `export const ${name} = undefined;`
|
|
2075
|
-
).join("\n"),
|
|
2076
|
-
map: null
|
|
2077
|
-
};
|
|
2078
|
-
}
|
|
2079
|
-
}
|
|
2080
|
-
},
|
|
2081
|
-
plugin,
|
|
2082
|
-
{
|
|
2083
|
-
name: "react-router:route-exports",
|
|
2084
|
-
async transform(code, id, options) {
|
|
2085
|
-
let route = getRoute(ctx.reactRouterConfig, id);
|
|
2086
|
-
if (!route) return;
|
|
2087
|
-
if (!options?.ssr && !ctx.reactRouterConfig.ssr) {
|
|
2088
|
-
let serverOnlyExports = esModuleLexer(code)[1].map((exp) => exp.n).filter((exp) => SERVER_ONLY_ROUTE_EXPORTS.includes(exp));
|
|
2089
|
-
if (serverOnlyExports.length > 0) {
|
|
2090
|
-
let str = serverOnlyExports.map((e) => `\`${e}\``).join(", ");
|
|
2091
|
-
let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://remix.run/guides/spa-mode for more information.`;
|
|
2092
|
-
throw Error(message);
|
|
2093
|
-
}
|
|
2094
|
-
if (route.id !== "root") {
|
|
2095
|
-
let hasHydrateFallback = esModuleLexer(code)[1].map((exp) => exp.n).some((exp) => exp === "HydrateFallback");
|
|
2096
|
-
if (hasHydrateFallback) {
|
|
2097
|
-
let message = `SPA Mode: Invalid \`HydrateFallback\` export found in \`${route.file}\`. \`HydrateFallback\` is only permitted on the root route in SPA Mode. See https://remix.run/guides/spa-mode for more information.`;
|
|
2098
|
-
throw Error(message);
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
}
|
|
2102
|
-
let [filepath] = id.split("?");
|
|
2103
|
-
let ast = parse(code, { sourceType: "module" });
|
|
2104
|
-
if (!options?.ssr) {
|
|
2105
|
-
removeExports(ast, SERVER_ONLY_ROUTE_EXPORTS);
|
|
2106
|
-
}
|
|
2107
|
-
transform(ast);
|
|
2108
|
-
return generate2(ast, {
|
|
2109
|
-
sourceMaps: true,
|
|
2110
|
-
filename: id,
|
|
2111
|
-
sourceFileName: filepath
|
|
2112
|
-
});
|
|
2113
|
-
}
|
|
2114
|
-
},
|
|
2115
|
-
{
|
|
2116
|
-
name: "react-router:inject-hmr-runtime",
|
|
2117
|
-
enforce: "pre",
|
|
2118
|
-
resolveId(id) {
|
|
2119
|
-
if (id === virtualInjectHmrRuntime.id) {
|
|
2120
|
-
return virtualInjectHmrRuntime.resolvedId;
|
|
2121
|
-
}
|
|
2122
|
-
},
|
|
2123
|
-
async load(id) {
|
|
2124
|
-
if (id !== virtualInjectHmrRuntime.resolvedId) return;
|
|
2125
|
-
return [
|
|
2126
|
-
`import RefreshRuntime from "${virtualHmrRuntime.id}"`,
|
|
2127
|
-
"RefreshRuntime.injectIntoGlobalHook(window)",
|
|
2128
|
-
"window.$RefreshReg$ = () => {}",
|
|
2129
|
-
"window.$RefreshSig$ = () => (type) => type",
|
|
2130
|
-
"window.__vite_plugin_react_preamble_installed__ = true"
|
|
2131
|
-
].join("\n");
|
|
2132
|
-
}
|
|
2133
|
-
},
|
|
2134
|
-
{
|
|
2135
|
-
name: "react-router:hmr-runtime",
|
|
2136
|
-
enforce: "pre",
|
|
2137
|
-
resolveId(id) {
|
|
2138
|
-
if (id === virtualHmrRuntime.id) return virtualHmrRuntime.resolvedId;
|
|
2139
|
-
},
|
|
2140
|
-
async load(id) {
|
|
2141
|
-
if (id !== virtualHmrRuntime.resolvedId) return;
|
|
2142
|
-
let reactRefreshDir = path4.dirname(
|
|
2143
|
-
require4.resolve("react-refresh/package.json")
|
|
2144
|
-
);
|
|
2145
|
-
let reactRefreshRuntimePath = path4.join(
|
|
2146
|
-
reactRefreshDir,
|
|
2147
|
-
"cjs/react-refresh-runtime.development.js"
|
|
2148
|
-
);
|
|
2149
|
-
return [
|
|
2150
|
-
"const exports = {}",
|
|
2151
|
-
await fse.readFile(reactRefreshRuntimePath, "utf8"),
|
|
2152
|
-
await fse.readFile(
|
|
2153
|
-
require4.resolve("./static/refresh-utils.cjs"),
|
|
2154
|
-
"utf8"
|
|
2155
|
-
),
|
|
2156
|
-
"export default exports"
|
|
2157
|
-
].join("\n");
|
|
2158
|
-
}
|
|
2159
|
-
},
|
|
2160
|
-
{
|
|
2161
|
-
name: "react-router:react-refresh-babel",
|
|
2162
|
-
async transform(code, id, options) {
|
|
2163
|
-
if (viteCommand !== "serve") return;
|
|
2164
|
-
if (id.includes("/node_modules/")) return;
|
|
2165
|
-
let [filepath] = id.split("?");
|
|
2166
|
-
let extensionsRE = /\.(jsx?|tsx?|mdx?)$/;
|
|
2167
|
-
if (!extensionsRE.test(filepath)) return;
|
|
2168
|
-
let devRuntime = "react/jsx-dev-runtime";
|
|
2169
|
-
let ssr = options?.ssr === true;
|
|
2170
|
-
let isJSX = filepath.endsWith("x");
|
|
2171
|
-
let useFastRefresh = !ssr && (isJSX || code.includes(devRuntime));
|
|
2172
|
-
if (!useFastRefresh) return;
|
|
2173
|
-
let result = await babel.transformAsync(code, {
|
|
2174
|
-
babelrc: false,
|
|
2175
|
-
configFile: false,
|
|
2176
|
-
filename: id,
|
|
2177
|
-
sourceFileName: filepath,
|
|
2178
|
-
parserOpts: {
|
|
2179
|
-
sourceType: "module",
|
|
2180
|
-
allowAwaitOutsideFunction: true
|
|
2181
|
-
},
|
|
2182
|
-
plugins: [[require4("react-refresh/babel"), { skipEnvCheck: true }]],
|
|
2183
|
-
sourceMaps: true
|
|
2184
|
-
});
|
|
2185
|
-
if (result === null) return;
|
|
2186
|
-
code = result.code;
|
|
2187
|
-
let refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/;
|
|
2188
|
-
if (refreshContentRE.test(code)) {
|
|
2189
|
-
code = addRefreshWrapper(ctx.reactRouterConfig, code, id);
|
|
2190
|
-
}
|
|
2191
|
-
return { code, map: result.map };
|
|
2192
|
-
}
|
|
2193
|
-
},
|
|
2194
|
-
{
|
|
2195
|
-
name: "react-router:hmr-updates",
|
|
2196
|
-
async handleHotUpdate({ server, file, modules, read }) {
|
|
2197
|
-
let route = getRoute(ctx.reactRouterConfig, file);
|
|
2198
|
-
let hmrEventData = { route: null };
|
|
2199
|
-
if (route) {
|
|
2200
|
-
let serverManifest = (await server.ssrLoadModule(virtual.serverManifest.id)).default;
|
|
2201
|
-
let oldRouteMetadata = serverManifest.routes[route.id];
|
|
2202
|
-
let newRouteMetadata = await getRouteMetadata(
|
|
2203
|
-
ctx,
|
|
2204
|
-
viteChildCompiler,
|
|
2205
|
-
route,
|
|
2206
|
-
read
|
|
2207
|
-
);
|
|
2208
|
-
hmrEventData.route = newRouteMetadata;
|
|
2209
|
-
if (!oldRouteMetadata || [
|
|
2210
|
-
"hasLoader",
|
|
2211
|
-
"hasClientLoader",
|
|
2212
|
-
"hasAction",
|
|
2213
|
-
"hasClientAction",
|
|
2214
|
-
"hasErrorBoundary"
|
|
2215
|
-
].some((key) => oldRouteMetadata[key] !== newRouteMetadata[key])) {
|
|
2216
|
-
invalidateVirtualModules(server);
|
|
2217
|
-
}
|
|
2218
|
-
}
|
|
2219
|
-
server.hot.send({
|
|
2220
|
-
type: "custom",
|
|
2221
|
-
event: "react-router:hmr",
|
|
2222
|
-
data: hmrEventData
|
|
2223
|
-
});
|
|
2224
|
-
return modules;
|
|
2225
|
-
}
|
|
2226
|
-
},
|
|
2227
|
-
{
|
|
2228
|
-
name: "react-router-server-change-trigger-client-hmr",
|
|
2229
|
-
// This hook is only available in Vite v6+ so this is a no-op in v5.
|
|
2230
|
-
// Previously the server and client modules were shared in a single module
|
|
2231
|
-
// graph. This meant that changes to server code automatically resulted in
|
|
2232
|
-
// client HMR updates. In Vite v6+ these module graphs are separate from
|
|
2233
|
-
// each other so we need to manually trigger client HMR updates if server
|
|
2234
|
-
// code has changed.
|
|
2235
|
-
hotUpdate({ server, modules }) {
|
|
2236
|
-
if (this.environment.name !== "ssr" && modules.length <= 0) {
|
|
2237
|
-
return;
|
|
2238
|
-
}
|
|
2239
|
-
let clientModules = uniqueNodes(
|
|
2240
|
-
modules.flatMap(
|
|
2241
|
-
(mod) => getParentClientNodes(server.environments.client.moduleGraph, mod)
|
|
2242
|
-
)
|
|
2243
|
-
);
|
|
2244
|
-
for (let clientModule of clientModules) {
|
|
2245
|
-
server.environments.client.reloadModule(clientModule);
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
}
|
|
2249
|
-
];
|
|
2250
|
-
};
|
|
2251
|
-
function getParentClientNodes(clientModuleGraph, module) {
|
|
2252
|
-
if (!module.id) {
|
|
2253
|
-
return [];
|
|
2254
|
-
}
|
|
2255
|
-
let clientModule = clientModuleGraph.getModuleById(module.id);
|
|
2256
|
-
if (clientModule) {
|
|
2257
|
-
return [clientModule];
|
|
2258
|
-
}
|
|
2259
|
-
return [...module.importers].flatMap(
|
|
2260
|
-
(importer) => getParentClientNodes(clientModuleGraph, importer)
|
|
2261
|
-
);
|
|
2262
|
-
}
|
|
2263
|
-
function uniqueNodes(nodes) {
|
|
2264
|
-
let nodeUrls = /* @__PURE__ */ new Set();
|
|
2265
|
-
let unique = [];
|
|
2266
|
-
for (let node of nodes) {
|
|
2267
|
-
if (nodeUrls.has(node.url)) {
|
|
2268
|
-
continue;
|
|
2269
|
-
}
|
|
2270
|
-
nodeUrls.add(node.url);
|
|
2271
|
-
unique.push(node);
|
|
2272
|
-
}
|
|
2273
|
-
return unique;
|
|
2274
|
-
}
|
|
2275
|
-
function findConfig(dir, basename2, extensions) {
|
|
2276
|
-
for (let ext of extensions) {
|
|
2277
|
-
let name = basename2 + ext;
|
|
2278
|
-
let file = path4.join(dir, name);
|
|
2279
|
-
if (fse.existsSync(file)) return file;
|
|
2280
|
-
}
|
|
2281
|
-
return void 0;
|
|
2282
|
-
}
|
|
2283
|
-
function addRefreshWrapper(reactRouterConfig, code, id) {
|
|
2284
|
-
let route = getRoute(reactRouterConfig, id);
|
|
2285
|
-
let acceptExports = route ? [
|
|
2286
|
-
"clientAction",
|
|
2287
|
-
"clientLoader",
|
|
2288
|
-
"handle",
|
|
2289
|
-
"meta",
|
|
2290
|
-
"links",
|
|
2291
|
-
"shouldRevalidate"
|
|
2292
|
-
] : [];
|
|
2293
|
-
return REACT_REFRESH_HEADER.replaceAll("__SOURCE__", JSON.stringify(id)) + code + REACT_REFRESH_FOOTER.replaceAll("__SOURCE__", JSON.stringify(id)).replaceAll("__ACCEPT_EXPORTS__", JSON.stringify(acceptExports)).replaceAll("__ROUTE_ID__", JSON.stringify(route?.id));
|
|
2294
|
-
}
|
|
2295
|
-
var REACT_REFRESH_HEADER = `
|
|
2296
|
-
import RefreshRuntime from "${virtualHmrRuntime.id}";
|
|
2297
|
-
|
|
2298
|
-
const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
|
|
2299
|
-
let prevRefreshReg;
|
|
2300
|
-
let prevRefreshSig;
|
|
2301
|
-
|
|
2302
|
-
if (import.meta.hot && !inWebWorker) {
|
|
2303
|
-
if (!window.__vite_plugin_react_preamble_installed__) {
|
|
2304
|
-
throw new Error(
|
|
2305
|
-
"React Router Vite plugin can't detect preamble. Something is wrong."
|
|
2306
|
-
);
|
|
2307
|
-
}
|
|
2308
|
-
|
|
2309
|
-
prevRefreshReg = window.$RefreshReg$;
|
|
2310
|
-
prevRefreshSig = window.$RefreshSig$;
|
|
2311
|
-
window.$RefreshReg$ = (type, id) => {
|
|
2312
|
-
RefreshRuntime.register(type, __SOURCE__ + " " + id)
|
|
2313
|
-
};
|
|
2314
|
-
window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
|
|
2315
|
-
}`.replaceAll("\n", "");
|
|
2316
|
-
var REACT_REFRESH_FOOTER = `
|
|
2317
|
-
if (import.meta.hot && !inWebWorker) {
|
|
2318
|
-
window.$RefreshReg$ = prevRefreshReg;
|
|
2319
|
-
window.$RefreshSig$ = prevRefreshSig;
|
|
2320
|
-
RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
|
|
2321
|
-
RefreshRuntime.registerExportsForReactRefresh(__SOURCE__, currentExports);
|
|
2322
|
-
import.meta.hot.accept((nextExports) => {
|
|
2323
|
-
if (!nextExports) return;
|
|
2324
|
-
__ROUTE_ID__ && window.__reactRouterRouteModuleUpdates.set(__ROUTE_ID__, nextExports);
|
|
2325
|
-
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(currentExports, nextExports, __ACCEPT_EXPORTS__);
|
|
2326
|
-
if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
|
|
2327
|
-
});
|
|
2328
|
-
});
|
|
2329
|
-
}`;
|
|
2330
|
-
function getRoute(pluginConfig, file) {
|
|
2331
|
-
let vite = getVite();
|
|
2332
|
-
let routePath = vite.normalizePath(
|
|
2333
|
-
path4.relative(pluginConfig.appDirectory, file)
|
|
2334
|
-
);
|
|
2335
|
-
let route = Object.values(pluginConfig.routes).find(
|
|
2336
|
-
(r) => vite.normalizePath(r.file) === routePath
|
|
2337
|
-
);
|
|
2338
|
-
return route;
|
|
2339
|
-
}
|
|
2340
|
-
async function getRouteMetadata(ctx, viteChildCompiler, route, readRouteFile) {
|
|
2341
|
-
let sourceExports = await getRouteModuleExports(
|
|
2342
|
-
viteChildCompiler,
|
|
2343
|
-
ctx,
|
|
2344
|
-
route.file,
|
|
2345
|
-
readRouteFile
|
|
2346
|
-
);
|
|
2347
|
-
let info = {
|
|
2348
|
-
id: route.id,
|
|
2349
|
-
parentId: route.parentId,
|
|
2350
|
-
path: route.path,
|
|
2351
|
-
index: route.index,
|
|
2352
|
-
caseSensitive: route.caseSensitive,
|
|
2353
|
-
url: combineURLs(
|
|
2354
|
-
ctx.publicPath,
|
|
2355
|
-
"/" + path4.relative(
|
|
2356
|
-
ctx.rootDirectory,
|
|
2357
|
-
resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
2358
|
-
)
|
|
2359
|
-
),
|
|
2360
|
-
module: combineURLs(
|
|
2361
|
-
ctx.publicPath,
|
|
2362
|
-
`${resolveFileUrl(
|
|
2363
|
-
ctx,
|
|
2364
|
-
resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
2365
|
-
)}?import`
|
|
2366
|
-
),
|
|
2367
|
-
// Ensure the Vite dev server responds with a JS module
|
|
2368
|
-
hasAction: sourceExports.includes("action"),
|
|
2369
|
-
hasClientAction: sourceExports.includes("clientAction"),
|
|
2370
|
-
hasLoader: sourceExports.includes("loader"),
|
|
2371
|
-
hasClientLoader: sourceExports.includes("clientLoader"),
|
|
2372
|
-
hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
|
|
2373
|
-
imports: []
|
|
2374
|
-
};
|
|
2375
|
-
return info;
|
|
2376
|
-
}
|
|
2377
|
-
async function getPrerenderBuildAndHandler(viteConfig, reactRouterConfig, serverBuildDirectory) {
|
|
2378
|
-
let serverBuildPath = path4.join(
|
|
2379
|
-
serverBuildDirectory,
|
|
2380
|
-
reactRouterConfig.serverBuildFile
|
|
2381
|
-
);
|
|
2382
|
-
let build = await import(url.pathToFileURL(serverBuildPath).toString());
|
|
2383
|
-
let { createRequestHandler: createHandler } = await import("react-router");
|
|
2384
|
-
return {
|
|
2385
|
-
build,
|
|
2386
|
-
handler: createHandler(build, viteConfig.mode)
|
|
2387
|
-
};
|
|
2388
|
-
}
|
|
2389
|
-
async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory, clientBuildDirectory) {
|
|
2390
|
-
let { handler } = await getPrerenderBuildAndHandler(
|
|
2391
|
-
viteConfig,
|
|
2392
|
-
reactRouterConfig,
|
|
2393
|
-
serverBuildDirectory
|
|
2394
|
-
);
|
|
2395
|
-
let request = new Request(`http://localhost${reactRouterConfig.basename}`);
|
|
2396
|
-
let response = await handler(request);
|
|
2397
|
-
let html = await response.text();
|
|
2398
|
-
validatePrerenderedResponse(response, html, "SPA Mode", "/");
|
|
2399
|
-
validatePrerenderedHtml(html, "SPA Mode");
|
|
2400
|
-
await fse.writeFile(path4.join(clientBuildDirectory, "index.html"), html);
|
|
2401
|
-
viteConfig.logger.info(
|
|
2402
|
-
"SPA Mode: index.html has been written to your " + colors2.bold(path4.relative(process.cwd(), clientBuildDirectory)) + " directory"
|
|
2403
|
-
);
|
|
2404
|
-
}
|
|
2405
|
-
async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirectory, clientBuildDirectory) {
|
|
2406
|
-
let { build, handler } = await getPrerenderBuildAndHandler(
|
|
2407
|
-
viteConfig,
|
|
2408
|
-
reactRouterConfig,
|
|
2409
|
-
serverBuildDirectory
|
|
2410
|
-
);
|
|
2411
|
-
let routes = createPrerenderRoutes(build.routes);
|
|
2412
|
-
let routesToPrerender;
|
|
2413
|
-
if (typeof reactRouterConfig.prerender === "boolean") {
|
|
2414
|
-
invariant(reactRouterConfig.prerender, "Expected prerender:true");
|
|
2415
|
-
routesToPrerender = determineStaticPrerenderRoutes(
|
|
2416
|
-
routes,
|
|
2417
|
-
viteConfig,
|
|
2418
|
-
true
|
|
2419
|
-
);
|
|
2420
|
-
} else if (typeof reactRouterConfig.prerender === "function") {
|
|
2421
|
-
routesToPrerender = await reactRouterConfig.prerender({
|
|
2422
|
-
getStaticPaths: () => determineStaticPrerenderRoutes(routes, viteConfig, false)
|
|
2423
|
-
});
|
|
2424
|
-
} else {
|
|
2425
|
-
routesToPrerender = reactRouterConfig.prerender || ["/"];
|
|
2426
|
-
}
|
|
2427
|
-
let headers = {
|
|
2428
|
-
// Header that can be used in the loader to know if you're running at
|
|
2429
|
-
// build time or runtime
|
|
2430
|
-
"X-React-Router-Prerender": "yes"
|
|
2431
|
-
};
|
|
2432
|
-
for (let path5 of routesToPrerender) {
|
|
2433
|
-
let matches = matchRoutes2(routes, `/${path5}/`.replace(/^\/\/+/, "/"));
|
|
2434
|
-
let hasLoaders = matches?.some((m) => m.route.loader);
|
|
2435
|
-
let data;
|
|
2436
|
-
if (hasLoaders) {
|
|
2437
|
-
data = await prerenderData(
|
|
2438
|
-
handler,
|
|
2439
|
-
path5,
|
|
2440
|
-
clientBuildDirectory,
|
|
2441
|
-
reactRouterConfig,
|
|
2442
|
-
viteConfig,
|
|
2443
|
-
{ headers }
|
|
2444
|
-
);
|
|
2445
|
-
}
|
|
2446
|
-
let leafRoute = matches ? matches[matches.length - 1].route : null;
|
|
2447
|
-
let manifestRoute = leafRoute ? build.routes[leafRoute.id]?.module : null;
|
|
2448
|
-
let isResourceRoute = manifestRoute && !manifestRoute.default && !manifestRoute.ErrorBoundary && manifestRoute.loader;
|
|
2449
|
-
if (isResourceRoute) {
|
|
2450
|
-
await prerenderResourceRoute(
|
|
2451
|
-
handler,
|
|
2452
|
-
path5,
|
|
2453
|
-
clientBuildDirectory,
|
|
2454
|
-
reactRouterConfig,
|
|
2455
|
-
viteConfig,
|
|
2456
|
-
{ headers }
|
|
2457
|
-
);
|
|
2458
|
-
} else {
|
|
2459
|
-
await prerenderRoute(
|
|
2460
|
-
handler,
|
|
2461
|
-
path5,
|
|
2462
|
-
clientBuildDirectory,
|
|
2463
|
-
reactRouterConfig,
|
|
2464
|
-
viteConfig,
|
|
2465
|
-
data ? {
|
|
2466
|
-
headers: {
|
|
2467
|
-
...headers,
|
|
2468
|
-
"X-React-Router-Prerender-Data": encodeURI(data)
|
|
2469
|
-
}
|
|
2470
|
-
} : { headers }
|
|
2471
|
-
);
|
|
2472
|
-
}
|
|
2473
|
-
}
|
|
2474
|
-
await prerenderManifest(
|
|
2475
|
-
build,
|
|
2476
|
-
clientBuildDirectory,
|
|
2477
|
-
reactRouterConfig,
|
|
2478
|
-
viteConfig
|
|
2479
|
-
);
|
|
2480
|
-
}
|
|
2481
|
-
function determineStaticPrerenderRoutes(routes, viteConfig, isBooleanUsage = false) {
|
|
2482
|
-
let paths = ["/"];
|
|
2483
|
-
let paramRoutes = [];
|
|
2484
|
-
function recurse(subtree, prefix = "") {
|
|
2485
|
-
for (let route of subtree) {
|
|
2486
|
-
let newPath = [prefix, route.path].join("/").replace(/\/\/+/g, "/");
|
|
2487
|
-
if (route.path) {
|
|
2488
|
-
let segments = route.path.split("/");
|
|
2489
|
-
if (segments.some((s) => s.startsWith(":") || s === "*")) {
|
|
2490
|
-
paramRoutes.push(route.path);
|
|
2491
|
-
} else {
|
|
2492
|
-
paths.push(newPath);
|
|
2493
|
-
}
|
|
2494
|
-
}
|
|
2495
|
-
if (route.children) {
|
|
2496
|
-
recurse(route.children, newPath);
|
|
2497
|
-
}
|
|
2498
|
-
}
|
|
2499
|
-
}
|
|
2500
|
-
recurse(routes);
|
|
2501
|
-
if (isBooleanUsage && paramRoutes.length > 0) {
|
|
2502
|
-
viteConfig.logger.warn(
|
|
2503
|
-
[
|
|
2504
|
-
"\u26A0\uFE0F Paths with dynamic/splat params cannot be prerendered when using `prerender: true`.",
|
|
2505
|
-
"You may want to use the `prerender()` API to prerender the following paths:",
|
|
2506
|
-
...paramRoutes.map((p) => " - " + p)
|
|
2507
|
-
].join("\n")
|
|
2508
|
-
);
|
|
2509
|
-
}
|
|
2510
|
-
return paths.map((p) => p.replace(/\/\/+/g, "/").replace(/(.+)\/$/, "$1"));
|
|
2511
|
-
}
|
|
2512
|
-
async function prerenderData(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
2513
|
-
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath === "/" ? "/_root.data" : `${prerenderPath.replace(/\/$/, "")}.data`}`.replace(/\/\/+/g, "/");
|
|
2514
|
-
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
2515
|
-
let response = await handler(request);
|
|
2516
|
-
let data = await response.text();
|
|
2517
|
-
validatePrerenderedResponse(response, data, "Prerender", normalizedPath);
|
|
2518
|
-
let outdir = path4.relative(process.cwd(), clientBuildDirectory);
|
|
2519
|
-
let outfile = path4.join(outdir, ...normalizedPath.split("/"));
|
|
2520
|
-
await fse.ensureDir(path4.dirname(outfile));
|
|
2521
|
-
await fse.outputFile(outfile, data);
|
|
2522
|
-
viteConfig.logger.info(`Prerender: Generated ${colors2.bold(outfile)}`);
|
|
2523
|
-
return data;
|
|
2524
|
-
}
|
|
2525
|
-
async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
2526
|
-
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(
|
|
2527
|
-
/\/\/+/g,
|
|
2528
|
-
"/"
|
|
2529
|
-
);
|
|
2530
|
-
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
2531
|
-
let response = await handler(request);
|
|
2532
|
-
let html = await response.text();
|
|
2533
|
-
validatePrerenderedResponse(response, html, "Prerender", normalizedPath);
|
|
2534
|
-
if (!reactRouterConfig.ssr) {
|
|
2535
|
-
validatePrerenderedHtml(html, "Prerender");
|
|
2536
|
-
}
|
|
2537
|
-
let outdir = path4.relative(process.cwd(), clientBuildDirectory);
|
|
2538
|
-
let outfile = path4.join(outdir, ...normalizedPath.split("/"), "index.html");
|
|
2539
|
-
await fse.ensureDir(path4.dirname(outfile));
|
|
2540
|
-
await fse.outputFile(outfile, html);
|
|
2541
|
-
viteConfig.logger.info(`Prerender: Generated ${colors2.bold(outfile)}`);
|
|
2542
|
-
}
|
|
2543
|
-
async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
2544
|
-
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
|
|
2545
|
-
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
2546
|
-
let response = await handler(request);
|
|
2547
|
-
let text = await response.text();
|
|
2548
|
-
validatePrerenderedResponse(response, text, "Prerender", normalizedPath);
|
|
2549
|
-
let outdir = path4.relative(process.cwd(), clientBuildDirectory);
|
|
2550
|
-
let outfile = path4.join(outdir, ...normalizedPath.split("/"));
|
|
2551
|
-
await fse.ensureDir(path4.dirname(outfile));
|
|
2552
|
-
await fse.outputFile(outfile, text);
|
|
2553
|
-
viteConfig.logger.info(`Prerender: Generated ${colors2.bold(outfile)}`);
|
|
2554
|
-
}
|
|
2555
|
-
async function prerenderManifest(build, clientBuildDirectory, reactRouterConfig, viteConfig) {
|
|
2556
|
-
let normalizedPath = `${reactRouterConfig.basename}/__manifest`.replace(
|
|
2557
|
-
/\/\/+/g,
|
|
2558
|
-
"/"
|
|
2559
|
-
);
|
|
2560
|
-
let outdir = path4.relative(process.cwd(), clientBuildDirectory);
|
|
2561
|
-
let outfile = path4.join(outdir, ...normalizedPath.split("/"));
|
|
2562
|
-
await fse.ensureDir(path4.dirname(outfile));
|
|
2563
|
-
let manifestData = JSON.stringify(build.assets.routes);
|
|
2564
|
-
await fse.outputFile(outfile, manifestData);
|
|
2565
|
-
viteConfig.logger.info(`Prerender: Generated ${colors2.bold(outfile)}`);
|
|
2566
|
-
}
|
|
2567
|
-
function validatePrerenderedResponse(response, html, prefix, path5) {
|
|
2568
|
-
if (response.status !== 200) {
|
|
2569
|
-
throw new Error(
|
|
2570
|
-
`${prefix}: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${path5}\` path.
|
|
2571
|
-
${html}`
|
|
2572
|
-
);
|
|
2573
|
-
}
|
|
2574
|
-
}
|
|
2575
|
-
function validatePrerenderedHtml(html, prefix) {
|
|
2576
|
-
if (!html.includes("window.__reactRouterContext =") || !html.includes("window.__reactRouterRouteModules =")) {
|
|
2577
|
-
throw new Error(
|
|
2578
|
-
`${prefix}: Did you forget to include <Scripts/> in your root route? Your pre-rendered HTML files cannot hydrate without \`<Scripts />\`.`
|
|
2579
|
-
);
|
|
2580
|
-
}
|
|
2581
|
-
}
|
|
2582
|
-
function groupRoutesByParentId2(manifest) {
|
|
2583
|
-
let routes = {};
|
|
2584
|
-
Object.values(manifest).forEach((route) => {
|
|
2585
|
-
if (route) {
|
|
2586
|
-
let parentId = route.parentId || "";
|
|
2587
|
-
if (!routes[parentId]) {
|
|
2588
|
-
routes[parentId] = [];
|
|
2589
|
-
}
|
|
2590
|
-
routes[parentId].push(route);
|
|
2591
|
-
}
|
|
2592
|
-
});
|
|
2593
|
-
return routes;
|
|
2594
|
-
}
|
|
2595
|
-
function createPrerenderRoutes(manifest, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) {
|
|
2596
|
-
return (routesByParentId[parentId] || []).map((route) => {
|
|
2597
|
-
let commonRoute = {
|
|
2598
|
-
// Always include root due to default boundaries
|
|
2599
|
-
hasErrorBoundary: route.id === "root" || route.module.ErrorBoundary != null,
|
|
2600
|
-
id: route.id,
|
|
2601
|
-
path: route.path,
|
|
2602
|
-
loader: route.module.loader ? () => null : void 0,
|
|
2603
|
-
action: void 0,
|
|
2604
|
-
handle: route.module.handle
|
|
2605
|
-
};
|
|
2606
|
-
return route.index ? {
|
|
2607
|
-
index: true,
|
|
2608
|
-
...commonRoute
|
|
2609
|
-
} : {
|
|
2610
|
-
caseSensitive: route.caseSensitive,
|
|
2611
|
-
children: createPrerenderRoutes(manifest, route.id, routesByParentId),
|
|
2612
|
-
...commonRoute
|
|
2613
|
-
};
|
|
2614
|
-
});
|
|
2615
|
-
}
|
|
2616
|
-
|
|
2617
|
-
export {
|
|
2618
|
-
configRouteToBranchRoute,
|
|
2619
|
-
run,
|
|
2620
|
-
watch,
|
|
2621
|
-
resolveViteConfig,
|
|
2622
|
-
extractPluginContext,
|
|
2623
|
-
loadPluginContext,
|
|
2624
|
-
getServerBuildDirectory,
|
|
2625
|
-
reactRouterVitePlugin
|
|
2626
|
-
};
|