@react-router/dev 7.1.5 → 7.2.0-pre.1
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/CHANGELOG.md +88 -1
- package/bin.js +2 -2
- package/dist/cli/index.js +635 -248
- package/dist/config.d.ts +8 -0
- package/dist/config.js +1 -1
- package/dist/routes.js +1 -1
- package/dist/static/refresh-utils.cjs +1 -1
- package/dist/vite/cloudflare.js +487 -3
- package/dist/vite.js +1711 -327
- package/package.json +6 -6
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v7.1
|
|
2
|
+
* @react-router/dev v7.2.0-pre.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -52,11 +52,14 @@ var fse = __toESM(require("fs-extra"));
|
|
|
52
52
|
var babel = __toESM(require("@babel/core"));
|
|
53
53
|
var import_react_router2 = require("react-router");
|
|
54
54
|
var import_es_module_lexer = require("es-module-lexer");
|
|
55
|
+
var import_pick3 = __toESM(require("lodash/pick"));
|
|
55
56
|
var import_jsesc = __toESM(require("jsesc"));
|
|
56
57
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
58
|
+
var import_kebabCase = __toESM(require("lodash/kebabCase"));
|
|
57
59
|
|
|
58
60
|
// typegen/index.ts
|
|
59
61
|
var import_node_fs2 = __toESM(require("fs"));
|
|
62
|
+
var import_dedent2 = __toESM(require("dedent"));
|
|
60
63
|
var Path4 = __toESM(require("pathe"));
|
|
61
64
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
62
65
|
|
|
@@ -270,6 +273,13 @@ var detectPackageManager = () => {
|
|
|
270
273
|
|
|
271
274
|
// config/config.ts
|
|
272
275
|
var excludedConfigPresetKeys = ["presets"];
|
|
276
|
+
var branchRouteProperties = [
|
|
277
|
+
"id",
|
|
278
|
+
"path",
|
|
279
|
+
"file",
|
|
280
|
+
"index"
|
|
281
|
+
];
|
|
282
|
+
var configRouteToBranchRoute = (configRoute) => (0, import_pick2.default)(configRoute, branchRouteProperties);
|
|
273
283
|
var mergeReactRouterConfig = (...configs) => {
|
|
274
284
|
let reducer = (configA, configB) => {
|
|
275
285
|
let mergeRequired = (key) => configA[key] !== void 0 && configB[key] !== void 0;
|
|
@@ -443,7 +453,9 @@ async function resolveConfig({
|
|
|
443
453
|
);
|
|
444
454
|
}
|
|
445
455
|
let future = {
|
|
446
|
-
unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false
|
|
456
|
+
unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
|
|
457
|
+
unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false,
|
|
458
|
+
unstable_viteEnvironmentApi: reactRouterUserConfig.future?.unstable_viteEnvironmentApi ?? false
|
|
447
459
|
};
|
|
448
460
|
let reactRouterConfig = deepFreeze({
|
|
449
461
|
appDirectory,
|
|
@@ -622,6 +634,19 @@ function findEntry(dir, basename2, options) {
|
|
|
622
634
|
return void 0;
|
|
623
635
|
}
|
|
624
636
|
|
|
637
|
+
// vite/babel.ts
|
|
638
|
+
var babel_exports = {};
|
|
639
|
+
__export(babel_exports, {
|
|
640
|
+
generate: () => generate,
|
|
641
|
+
parse: () => import_parser.parse,
|
|
642
|
+
t: () => t,
|
|
643
|
+
traverse: () => traverse
|
|
644
|
+
});
|
|
645
|
+
var import_parser = require("@babel/parser");
|
|
646
|
+
var t = __toESM(require("@babel/types"));
|
|
647
|
+
var traverse = require("@babel/traverse").default;
|
|
648
|
+
var generate = require("@babel/generator").default;
|
|
649
|
+
|
|
625
650
|
// typegen/generate.ts
|
|
626
651
|
var import_dedent = __toESM(require("dedent"));
|
|
627
652
|
var Path3 = __toESM(require("pathe"));
|
|
@@ -642,12 +667,45 @@ function getTypesPath(ctx, route) {
|
|
|
642
667
|
);
|
|
643
668
|
}
|
|
644
669
|
|
|
670
|
+
// typegen/params.ts
|
|
671
|
+
function parse2(fullpath2) {
|
|
672
|
+
const result = {};
|
|
673
|
+
let segments = fullpath2.split("/");
|
|
674
|
+
segments.forEach((segment) => {
|
|
675
|
+
const match = segment.match(/^:([\w-]+)(\?)?/);
|
|
676
|
+
if (!match) return;
|
|
677
|
+
const param = match[1];
|
|
678
|
+
const isRequired = match[2] === void 0;
|
|
679
|
+
result[param] ||= isRequired;
|
|
680
|
+
return;
|
|
681
|
+
});
|
|
682
|
+
const hasSplat = segments.at(-1) === "*";
|
|
683
|
+
if (hasSplat) result["*"] = true;
|
|
684
|
+
return result;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// typegen/route.ts
|
|
688
|
+
function lineage(routes, route) {
|
|
689
|
+
const result = [];
|
|
690
|
+
while (route) {
|
|
691
|
+
result.push(route);
|
|
692
|
+
if (!route.parentId) break;
|
|
693
|
+
route = routes[route.parentId];
|
|
694
|
+
}
|
|
695
|
+
result.reverse();
|
|
696
|
+
return result;
|
|
697
|
+
}
|
|
698
|
+
function fullpath(lineage2) {
|
|
699
|
+
if (lineage2.length === 1 && lineage2[0].id === "root") return "/";
|
|
700
|
+
return "/" + lineage2.map((route) => route.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path7) => path7 !== void 0 && path7 !== "").join("/");
|
|
701
|
+
}
|
|
702
|
+
|
|
645
703
|
// typegen/generate.ts
|
|
646
|
-
function
|
|
647
|
-
const
|
|
648
|
-
const
|
|
704
|
+
function generate2(ctx, route) {
|
|
705
|
+
const lineage2 = lineage(ctx.config.routes, route);
|
|
706
|
+
const fullpath2 = fullpath(lineage2);
|
|
649
707
|
const typesPath = getTypesPath(ctx, route);
|
|
650
|
-
const parents =
|
|
708
|
+
const parents = lineage2.slice(0, -1);
|
|
651
709
|
const parentTypeImports = parents.map((parent, i) => {
|
|
652
710
|
const rel = Path3.relative(
|
|
653
711
|
Path3.dirname(typesPath),
|
|
@@ -674,7 +732,7 @@ function generate(ctx, route) {
|
|
|
674
732
|
file: "${route.file}"
|
|
675
733
|
path: "${route.path}"
|
|
676
734
|
params: {${formatParamProperties(
|
|
677
|
-
|
|
735
|
+
fullpath2
|
|
678
736
|
)}} & { [key: string]: string | undefined }
|
|
679
737
|
module: Module
|
|
680
738
|
loaderData: T.CreateLoaderData<Module>
|
|
@@ -704,46 +762,13 @@ function generate(ctx, route) {
|
|
|
704
762
|
`;
|
|
705
763
|
}
|
|
706
764
|
var noExtension = (path7) => Path3.join(Path3.dirname(path7), Pathe2.filename(path7));
|
|
707
|
-
function
|
|
708
|
-
const
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
route = routes[route.parentId];
|
|
713
|
-
}
|
|
714
|
-
result.reverse();
|
|
715
|
-
return result;
|
|
716
|
-
}
|
|
717
|
-
function formatParamProperties(urlpath) {
|
|
718
|
-
const params = parseParams(urlpath);
|
|
719
|
-
const properties = Object.entries(params).map(([name, values]) => {
|
|
720
|
-
if (values.length === 1) {
|
|
721
|
-
const isOptional = values[0];
|
|
722
|
-
return isOptional ? `"${name}"?: string` : `"${name}": string`;
|
|
723
|
-
}
|
|
724
|
-
const items = values.map(
|
|
725
|
-
(isOptional) => isOptional ? "string | undefined" : "string"
|
|
726
|
-
);
|
|
727
|
-
return `"${name}": [${items.join(", ")}]`;
|
|
728
|
-
});
|
|
765
|
+
function formatParamProperties(fullpath2) {
|
|
766
|
+
const params = parse2(fullpath2);
|
|
767
|
+
const properties = Object.entries(params).map(
|
|
768
|
+
([name, isRequired]) => isRequired ? `"${name}": string` : `"${name}"?: string`
|
|
769
|
+
);
|
|
729
770
|
return properties.join("; ");
|
|
730
771
|
}
|
|
731
|
-
function parseParams(urlpath) {
|
|
732
|
-
const result = {};
|
|
733
|
-
let segments = urlpath.split("/");
|
|
734
|
-
segments.forEach((segment) => {
|
|
735
|
-
const match = segment.match(/^:([\w-]+)(\?)?/);
|
|
736
|
-
if (!match) return;
|
|
737
|
-
const param = match[1];
|
|
738
|
-
const isOptional = match[2] !== void 0;
|
|
739
|
-
result[param] ??= [];
|
|
740
|
-
result[param].push(isOptional);
|
|
741
|
-
return;
|
|
742
|
-
});
|
|
743
|
-
const hasSplat = segments.at(-1) === "*";
|
|
744
|
-
if (hasSplat) result["*"] = [false];
|
|
745
|
-
return result;
|
|
746
|
-
}
|
|
747
772
|
|
|
748
773
|
// typegen/index.ts
|
|
749
774
|
async function watch(rootDirectory, { logger } = {}) {
|
|
@@ -789,17 +814,53 @@ async function writeAll(ctx) {
|
|
|
789
814
|
import_node_fs2.default.rmSync(typegenDir, { recursive: true, force: true });
|
|
790
815
|
Object.values(ctx.config.routes).forEach((route) => {
|
|
791
816
|
const typesPath = getTypesPath(ctx, route);
|
|
792
|
-
const content =
|
|
817
|
+
const content = generate2(ctx, route);
|
|
793
818
|
import_node_fs2.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
|
|
794
819
|
import_node_fs2.default.writeFileSync(typesPath, content);
|
|
795
820
|
});
|
|
821
|
+
const registerPath = Path4.join(typegenDir, "+register.ts");
|
|
822
|
+
import_node_fs2.default.writeFileSync(registerPath, register(ctx));
|
|
796
823
|
}
|
|
824
|
+
function register(ctx) {
|
|
825
|
+
const register2 = import_dedent2.default`
|
|
826
|
+
import "react-router";
|
|
797
827
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
828
|
+
declare module "react-router" {
|
|
829
|
+
interface Register {
|
|
830
|
+
params: Params;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
`;
|
|
834
|
+
const { t: t2 } = babel_exports;
|
|
835
|
+
const typeParams = t2.tsTypeAliasDeclaration(
|
|
836
|
+
t2.identifier("Params"),
|
|
837
|
+
null,
|
|
838
|
+
t2.tsTypeLiteral(
|
|
839
|
+
Object.values(ctx.config.routes).map((route) => {
|
|
840
|
+
if (route.id !== "root" && !route.path) return void 0;
|
|
841
|
+
const lineage2 = lineage(ctx.config.routes, route);
|
|
842
|
+
const fullpath2 = fullpath(lineage2);
|
|
843
|
+
const params = parse2(fullpath2);
|
|
844
|
+
return t2.tsPropertySignature(
|
|
845
|
+
t2.stringLiteral(fullpath2),
|
|
846
|
+
t2.tsTypeAnnotation(
|
|
847
|
+
t2.tsTypeLiteral(
|
|
848
|
+
Object.entries(params).map(([param, isRequired]) => {
|
|
849
|
+
const property = t2.tsPropertySignature(
|
|
850
|
+
t2.stringLiteral(param),
|
|
851
|
+
t2.tsTypeAnnotation(t2.tsStringKeyword())
|
|
852
|
+
);
|
|
853
|
+
property.optional = !isRequired;
|
|
854
|
+
return property;
|
|
855
|
+
})
|
|
856
|
+
)
|
|
857
|
+
)
|
|
858
|
+
);
|
|
859
|
+
}).filter((x) => x !== void 0)
|
|
860
|
+
)
|
|
861
|
+
);
|
|
862
|
+
return [register2, generate(typeParams).code].join("\n\n");
|
|
863
|
+
}
|
|
803
864
|
|
|
804
865
|
// vite/node-adapter.ts
|
|
805
866
|
var import_node_events = require("events");
|
|
@@ -1159,8 +1220,613 @@ function invalidDestructureError(name) {
|
|
|
1159
1220
|
return new Error(`Cannot remove destructured export "${name}"`);
|
|
1160
1221
|
}
|
|
1161
1222
|
|
|
1223
|
+
// vite/cache.ts
|
|
1224
|
+
function getOrSetFromCache(cache, key, version, getValue) {
|
|
1225
|
+
if (!cache) {
|
|
1226
|
+
return getValue();
|
|
1227
|
+
}
|
|
1228
|
+
let entry = cache.get(key);
|
|
1229
|
+
if (entry?.version === version) {
|
|
1230
|
+
return entry.value;
|
|
1231
|
+
}
|
|
1232
|
+
let value = getValue();
|
|
1233
|
+
let newEntry = { value, version };
|
|
1234
|
+
cache.set(key, newEntry);
|
|
1235
|
+
return value;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// vite/route-chunks.ts
|
|
1239
|
+
function codeToAst(code, cache, cacheKey) {
|
|
1240
|
+
return structuredClone(
|
|
1241
|
+
getOrSetFromCache(
|
|
1242
|
+
cache,
|
|
1243
|
+
`${cacheKey}::codeToAst`,
|
|
1244
|
+
code,
|
|
1245
|
+
() => (0, import_parser.parse)(code, { sourceType: "module" })
|
|
1246
|
+
)
|
|
1247
|
+
);
|
|
1248
|
+
}
|
|
1249
|
+
function assertNodePath(path7) {
|
|
1250
|
+
invariant(
|
|
1251
|
+
path7 && !Array.isArray(path7),
|
|
1252
|
+
`Expected a Path, but got ${Array.isArray(path7) ? "an array" : path7}`
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
function assertNodePathIsStatement(path7) {
|
|
1256
|
+
invariant(
|
|
1257
|
+
path7 && !Array.isArray(path7) && t.isStatement(path7.node),
|
|
1258
|
+
`Expected a Statement path, but got ${Array.isArray(path7) ? "an array" : path7?.node?.type}`
|
|
1259
|
+
);
|
|
1260
|
+
}
|
|
1261
|
+
function assertNodePathIsVariableDeclarator(path7) {
|
|
1262
|
+
invariant(
|
|
1263
|
+
path7 && !Array.isArray(path7) && t.isVariableDeclarator(path7.node),
|
|
1264
|
+
`Expected an Identifier path, but got ${Array.isArray(path7) ? "an array" : path7?.node?.type}`
|
|
1265
|
+
);
|
|
1266
|
+
}
|
|
1267
|
+
function assertNodePathIsPattern(path7) {
|
|
1268
|
+
invariant(
|
|
1269
|
+
path7 && !Array.isArray(path7) && t.isPattern(path7.node),
|
|
1270
|
+
`Expected a Pattern path, but got ${Array.isArray(path7) ? "an array" : path7?.node?.type}`
|
|
1271
|
+
);
|
|
1272
|
+
}
|
|
1273
|
+
function getExportDependencies(code, cache, cacheKey) {
|
|
1274
|
+
return getOrSetFromCache(
|
|
1275
|
+
cache,
|
|
1276
|
+
`${cacheKey}::getExportDependencies`,
|
|
1277
|
+
code,
|
|
1278
|
+
() => {
|
|
1279
|
+
let exportDependencies = /* @__PURE__ */ new Map();
|
|
1280
|
+
let ast = codeToAst(code, cache, cacheKey);
|
|
1281
|
+
function handleExport(exportName, exportPath, identifiersPath = exportPath) {
|
|
1282
|
+
let identifiers = getDependentIdentifiersForPath(identifiersPath);
|
|
1283
|
+
let topLevelStatements = /* @__PURE__ */ new Set([
|
|
1284
|
+
exportPath.node,
|
|
1285
|
+
...getTopLevelStatementsForPaths(identifiers)
|
|
1286
|
+
]);
|
|
1287
|
+
let topLevelNonModuleStatements = new Set(
|
|
1288
|
+
Array.from(topLevelStatements).filter(
|
|
1289
|
+
(statement) => !t.isImportDeclaration(statement) && !t.isExportDeclaration(statement)
|
|
1290
|
+
)
|
|
1291
|
+
);
|
|
1292
|
+
let importedIdentifierNames = /* @__PURE__ */ new Set();
|
|
1293
|
+
for (let identifier of identifiers) {
|
|
1294
|
+
if (identifier.parentPath.parentPath?.isImportDeclaration()) {
|
|
1295
|
+
importedIdentifierNames.add(identifier.node.name);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
let exportedVariableDeclarators = /* @__PURE__ */ new Set();
|
|
1299
|
+
for (let identifier of identifiers) {
|
|
1300
|
+
if (identifier.parentPath.isVariableDeclarator() && identifier.parentPath.parentPath.parentPath?.isExportNamedDeclaration()) {
|
|
1301
|
+
exportedVariableDeclarators.add(identifier.parentPath.node);
|
|
1302
|
+
continue;
|
|
1303
|
+
}
|
|
1304
|
+
let isWithinExportDestructuring = Boolean(
|
|
1305
|
+
identifier.findParent(
|
|
1306
|
+
(path7) => Boolean(
|
|
1307
|
+
path7.isPattern() && path7.parentPath?.isVariableDeclarator() && path7.parentPath.parentPath?.parentPath?.isExportNamedDeclaration()
|
|
1308
|
+
)
|
|
1309
|
+
)
|
|
1310
|
+
);
|
|
1311
|
+
if (isWithinExportDestructuring) {
|
|
1312
|
+
let currentPath = identifier;
|
|
1313
|
+
while (currentPath) {
|
|
1314
|
+
if (
|
|
1315
|
+
// Check the identifier is within a variable declaration, and if
|
|
1316
|
+
// so, ensure we're on the left-hand side of the expression
|
|
1317
|
+
// since these identifiers are what make up the export names,
|
|
1318
|
+
// e.g. export const { foo } = { foo: bar }; should pick up
|
|
1319
|
+
// `foo` but not `bar`.
|
|
1320
|
+
currentPath.parentPath?.isVariableDeclarator() && currentPath.parentKey === "id"
|
|
1321
|
+
) {
|
|
1322
|
+
exportedVariableDeclarators.add(currentPath.parentPath.node);
|
|
1323
|
+
break;
|
|
1324
|
+
}
|
|
1325
|
+
currentPath = currentPath.parentPath;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
let dependencies = {
|
|
1330
|
+
topLevelStatements,
|
|
1331
|
+
topLevelNonModuleStatements,
|
|
1332
|
+
importedIdentifierNames,
|
|
1333
|
+
exportedVariableDeclarators
|
|
1334
|
+
};
|
|
1335
|
+
exportDependencies.set(exportName, dependencies);
|
|
1336
|
+
}
|
|
1337
|
+
traverse(ast, {
|
|
1338
|
+
ExportDeclaration(exportPath) {
|
|
1339
|
+
let { node } = exportPath;
|
|
1340
|
+
if (t.isExportAllDeclaration(node)) {
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
if (t.isExportDefaultDeclaration(node)) {
|
|
1344
|
+
handleExport("default", exportPath);
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
let { declaration } = node;
|
|
1348
|
+
if (t.isVariableDeclaration(declaration)) {
|
|
1349
|
+
let { declarations } = declaration;
|
|
1350
|
+
for (let i = 0; i < declarations.length; i++) {
|
|
1351
|
+
let declarator = declarations[i];
|
|
1352
|
+
if (t.isIdentifier(declarator.id)) {
|
|
1353
|
+
let declaratorPath = exportPath.get(
|
|
1354
|
+
`declaration.declarations.${i}`
|
|
1355
|
+
);
|
|
1356
|
+
assertNodePathIsVariableDeclarator(declaratorPath);
|
|
1357
|
+
handleExport(declarator.id.name, exportPath, declaratorPath);
|
|
1358
|
+
continue;
|
|
1359
|
+
}
|
|
1360
|
+
if (t.isPattern(declarator.id)) {
|
|
1361
|
+
let exportedPatternPath = exportPath.get(
|
|
1362
|
+
`declaration.declarations.${i}.id`
|
|
1363
|
+
);
|
|
1364
|
+
assertNodePathIsPattern(exportedPatternPath);
|
|
1365
|
+
let identifiers = getIdentifiersForPatternPath(exportedPatternPath);
|
|
1366
|
+
for (let identifier of identifiers) {
|
|
1367
|
+
handleExport(identifier.node.name, exportPath, identifier);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
if (t.isFunctionDeclaration(declaration) || t.isClassDeclaration(declaration)) {
|
|
1374
|
+
invariant(
|
|
1375
|
+
declaration.id,
|
|
1376
|
+
"Expected exported function or class declaration to have a name when not the default export"
|
|
1377
|
+
);
|
|
1378
|
+
handleExport(declaration.id.name, exportPath);
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
if (t.isExportNamedDeclaration(node)) {
|
|
1382
|
+
for (let specifier of node.specifiers) {
|
|
1383
|
+
if (t.isIdentifier(specifier.exported)) {
|
|
1384
|
+
let name = specifier.exported.name;
|
|
1385
|
+
let specifierPath = exportPath.get("specifiers").find((path7) => path7.node === specifier);
|
|
1386
|
+
invariant(
|
|
1387
|
+
specifierPath,
|
|
1388
|
+
`Expected to find specifier path for ${name}`
|
|
1389
|
+
);
|
|
1390
|
+
handleExport(name, exportPath, specifierPath);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
return;
|
|
1394
|
+
}
|
|
1395
|
+
throw new Error(`Unknown export node type: ${node.type}`);
|
|
1396
|
+
}
|
|
1397
|
+
});
|
|
1398
|
+
return exportDependencies;
|
|
1399
|
+
}
|
|
1400
|
+
);
|
|
1401
|
+
}
|
|
1402
|
+
function getDependentIdentifiersForPath(path7, state) {
|
|
1403
|
+
let { visited, identifiers } = state ?? {
|
|
1404
|
+
visited: /* @__PURE__ */ new Set(),
|
|
1405
|
+
identifiers: /* @__PURE__ */ new Set()
|
|
1406
|
+
};
|
|
1407
|
+
if (visited.has(path7)) {
|
|
1408
|
+
return identifiers;
|
|
1409
|
+
}
|
|
1410
|
+
visited.add(path7);
|
|
1411
|
+
path7.traverse({
|
|
1412
|
+
Identifier(path8) {
|
|
1413
|
+
if (identifiers.has(path8)) {
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
identifiers.add(path8);
|
|
1417
|
+
let binding = path8.scope.getBinding(path8.node.name);
|
|
1418
|
+
if (!binding) {
|
|
1419
|
+
return;
|
|
1420
|
+
}
|
|
1421
|
+
getDependentIdentifiersForPath(binding.path, { visited, identifiers });
|
|
1422
|
+
for (let reference of binding.referencePaths) {
|
|
1423
|
+
if (reference.isExportNamedDeclaration()) {
|
|
1424
|
+
continue;
|
|
1425
|
+
}
|
|
1426
|
+
getDependentIdentifiersForPath(reference, {
|
|
1427
|
+
visited,
|
|
1428
|
+
identifiers
|
|
1429
|
+
});
|
|
1430
|
+
}
|
|
1431
|
+
for (let constantViolation of binding.constantViolations) {
|
|
1432
|
+
getDependentIdentifiersForPath(constantViolation, {
|
|
1433
|
+
visited,
|
|
1434
|
+
identifiers
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
});
|
|
1439
|
+
let topLevelStatement = getTopLevelStatementPathForPath(path7);
|
|
1440
|
+
let withinImportStatement = topLevelStatement.isImportDeclaration();
|
|
1441
|
+
let withinExportStatement = topLevelStatement.isExportDeclaration();
|
|
1442
|
+
if (!withinImportStatement && !withinExportStatement) {
|
|
1443
|
+
getDependentIdentifiersForPath(topLevelStatement, {
|
|
1444
|
+
visited,
|
|
1445
|
+
identifiers
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
if (withinExportStatement && path7.isIdentifier() && (t.isPattern(path7.parentPath.node) || // [foo]
|
|
1449
|
+
t.isPattern(path7.parentPath.parentPath?.node))) {
|
|
1450
|
+
let variableDeclarator = path7.findParent((p) => p.isVariableDeclarator());
|
|
1451
|
+
assertNodePath(variableDeclarator);
|
|
1452
|
+
getDependentIdentifiersForPath(variableDeclarator, {
|
|
1453
|
+
visited,
|
|
1454
|
+
identifiers
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
return identifiers;
|
|
1458
|
+
}
|
|
1459
|
+
function getTopLevelStatementPathForPath(path7) {
|
|
1460
|
+
let ancestry = path7.getAncestry();
|
|
1461
|
+
let topLevelStatement = ancestry[ancestry.length - 2];
|
|
1462
|
+
assertNodePathIsStatement(topLevelStatement);
|
|
1463
|
+
return topLevelStatement;
|
|
1464
|
+
}
|
|
1465
|
+
function getTopLevelStatementsForPaths(paths) {
|
|
1466
|
+
let topLevelStatements = /* @__PURE__ */ new Set();
|
|
1467
|
+
for (let path7 of paths) {
|
|
1468
|
+
let topLevelStatement = getTopLevelStatementPathForPath(path7);
|
|
1469
|
+
topLevelStatements.add(topLevelStatement.node);
|
|
1470
|
+
}
|
|
1471
|
+
return topLevelStatements;
|
|
1472
|
+
}
|
|
1473
|
+
function getIdentifiersForPatternPath(patternPath, identifiers = /* @__PURE__ */ new Set()) {
|
|
1474
|
+
function walk(currentPath) {
|
|
1475
|
+
if (currentPath.isIdentifier()) {
|
|
1476
|
+
identifiers.add(currentPath);
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
if (currentPath.isObjectPattern()) {
|
|
1480
|
+
let { properties } = currentPath.node;
|
|
1481
|
+
for (let i = 0; i < properties.length; i++) {
|
|
1482
|
+
const property = properties[i];
|
|
1483
|
+
if (t.isObjectProperty(property)) {
|
|
1484
|
+
let valuePath = currentPath.get(`properties.${i}.value`);
|
|
1485
|
+
assertNodePath(valuePath);
|
|
1486
|
+
walk(valuePath);
|
|
1487
|
+
} else if (t.isRestElement(property)) {
|
|
1488
|
+
let argumentPath = currentPath.get(`properties.${i}.argument`);
|
|
1489
|
+
assertNodePath(argumentPath);
|
|
1490
|
+
walk(argumentPath);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
} else if (currentPath.isArrayPattern()) {
|
|
1494
|
+
let { elements } = currentPath.node;
|
|
1495
|
+
for (let i = 0; i < elements.length; i++) {
|
|
1496
|
+
const element = elements[i];
|
|
1497
|
+
if (element) {
|
|
1498
|
+
let elementPath = currentPath.get(`elements.${i}`);
|
|
1499
|
+
assertNodePath(elementPath);
|
|
1500
|
+
walk(elementPath);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
} else if (currentPath.isRestElement()) {
|
|
1504
|
+
let argumentPath = currentPath.get("argument");
|
|
1505
|
+
assertNodePath(argumentPath);
|
|
1506
|
+
walk(argumentPath);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
walk(patternPath);
|
|
1510
|
+
return identifiers;
|
|
1511
|
+
}
|
|
1512
|
+
var getExportedName = (exported) => {
|
|
1513
|
+
return t.isIdentifier(exported) ? exported.name : exported.value;
|
|
1514
|
+
};
|
|
1515
|
+
function setsIntersect(set1, set2) {
|
|
1516
|
+
let smallerSet = set1;
|
|
1517
|
+
let largerSet = set2;
|
|
1518
|
+
if (set1.size > set2.size) {
|
|
1519
|
+
smallerSet = set2;
|
|
1520
|
+
largerSet = set1;
|
|
1521
|
+
}
|
|
1522
|
+
for (let element of smallerSet) {
|
|
1523
|
+
if (largerSet.has(element)) {
|
|
1524
|
+
return true;
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
return false;
|
|
1528
|
+
}
|
|
1529
|
+
function hasChunkableExport(code, exportName, cache, cacheKey) {
|
|
1530
|
+
return getOrSetFromCache(
|
|
1531
|
+
cache,
|
|
1532
|
+
`${cacheKey}::hasChunkableExport::${exportName}`,
|
|
1533
|
+
code,
|
|
1534
|
+
() => {
|
|
1535
|
+
let exportDependencies = getExportDependencies(code, cache, cacheKey);
|
|
1536
|
+
let dependencies = exportDependencies.get(exportName);
|
|
1537
|
+
if (!dependencies) {
|
|
1538
|
+
return false;
|
|
1539
|
+
}
|
|
1540
|
+
for (let [currentExportName, currentDependencies] of exportDependencies) {
|
|
1541
|
+
if (currentExportName === exportName) {
|
|
1542
|
+
continue;
|
|
1543
|
+
}
|
|
1544
|
+
if (setsIntersect(
|
|
1545
|
+
currentDependencies.topLevelNonModuleStatements,
|
|
1546
|
+
dependencies.topLevelNonModuleStatements
|
|
1547
|
+
)) {
|
|
1548
|
+
return false;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
if (dependencies.exportedVariableDeclarators.size > 1) {
|
|
1552
|
+
return false;
|
|
1553
|
+
}
|
|
1554
|
+
if (dependencies.exportedVariableDeclarators.size > 0) {
|
|
1555
|
+
for (let [
|
|
1556
|
+
currentExportName,
|
|
1557
|
+
currentDependencies
|
|
1558
|
+
] of exportDependencies) {
|
|
1559
|
+
if (currentExportName === exportName) {
|
|
1560
|
+
continue;
|
|
1561
|
+
}
|
|
1562
|
+
if (setsIntersect(
|
|
1563
|
+
currentDependencies.exportedVariableDeclarators,
|
|
1564
|
+
dependencies.exportedVariableDeclarators
|
|
1565
|
+
)) {
|
|
1566
|
+
return false;
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
return true;
|
|
1571
|
+
}
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
function getChunkedExport(code, exportName, generateOptions = {}, cache, cacheKey) {
|
|
1575
|
+
return getOrSetFromCache(
|
|
1576
|
+
cache,
|
|
1577
|
+
`${cacheKey}::getChunkedExport::${exportName}::${JSON.stringify(
|
|
1578
|
+
generateOptions
|
|
1579
|
+
)}`,
|
|
1580
|
+
code,
|
|
1581
|
+
() => {
|
|
1582
|
+
if (!hasChunkableExport(code, exportName, cache, cacheKey)) {
|
|
1583
|
+
return void 0;
|
|
1584
|
+
}
|
|
1585
|
+
let exportDependencies = getExportDependencies(code, cache, cacheKey);
|
|
1586
|
+
let dependencies = exportDependencies.get(exportName);
|
|
1587
|
+
invariant(dependencies, "Expected export to have dependencies");
|
|
1588
|
+
let topLevelStatementsArray = Array.from(dependencies.topLevelStatements);
|
|
1589
|
+
let exportedVariableDeclaratorsArray = Array.from(
|
|
1590
|
+
dependencies.exportedVariableDeclarators
|
|
1591
|
+
);
|
|
1592
|
+
let ast = codeToAst(code, cache, cacheKey);
|
|
1593
|
+
ast.program.body = ast.program.body.filter(
|
|
1594
|
+
(node) => topLevelStatementsArray.some(
|
|
1595
|
+
(statement) => t.isNodesEquivalent(node, statement)
|
|
1596
|
+
)
|
|
1597
|
+
).map((node) => {
|
|
1598
|
+
if (!t.isImportDeclaration(node)) {
|
|
1599
|
+
return node;
|
|
1600
|
+
}
|
|
1601
|
+
if (dependencies.importedIdentifierNames.size === 0) {
|
|
1602
|
+
return null;
|
|
1603
|
+
}
|
|
1604
|
+
node.specifiers = node.specifiers.filter(
|
|
1605
|
+
(specifier) => dependencies.importedIdentifierNames.has(specifier.local.name)
|
|
1606
|
+
);
|
|
1607
|
+
invariant(
|
|
1608
|
+
node.specifiers.length > 0,
|
|
1609
|
+
"Expected import statement to have used specifiers"
|
|
1610
|
+
);
|
|
1611
|
+
return node;
|
|
1612
|
+
}).map((node) => {
|
|
1613
|
+
if (!t.isExportDeclaration(node)) {
|
|
1614
|
+
return node;
|
|
1615
|
+
}
|
|
1616
|
+
if (t.isExportAllDeclaration(node)) {
|
|
1617
|
+
return null;
|
|
1618
|
+
}
|
|
1619
|
+
if (t.isExportDefaultDeclaration(node)) {
|
|
1620
|
+
return exportName === "default" ? node : null;
|
|
1621
|
+
}
|
|
1622
|
+
let { declaration } = node;
|
|
1623
|
+
if (t.isVariableDeclaration(declaration)) {
|
|
1624
|
+
declaration.declarations = declaration.declarations.filter(
|
|
1625
|
+
(node2) => exportedVariableDeclaratorsArray.some(
|
|
1626
|
+
(declarator) => t.isNodesEquivalent(node2, declarator)
|
|
1627
|
+
)
|
|
1628
|
+
);
|
|
1629
|
+
if (declaration.declarations.length === 0) {
|
|
1630
|
+
return null;
|
|
1631
|
+
}
|
|
1632
|
+
return node;
|
|
1633
|
+
}
|
|
1634
|
+
if (t.isFunctionDeclaration(node.declaration) || t.isClassDeclaration(node.declaration)) {
|
|
1635
|
+
return node.declaration.id?.name === exportName ? node : null;
|
|
1636
|
+
}
|
|
1637
|
+
if (t.isExportNamedDeclaration(node)) {
|
|
1638
|
+
if (node.specifiers.length === 0) {
|
|
1639
|
+
return null;
|
|
1640
|
+
}
|
|
1641
|
+
node.specifiers = node.specifiers.filter(
|
|
1642
|
+
(specifier) => getExportedName(specifier.exported) === exportName
|
|
1643
|
+
);
|
|
1644
|
+
if (node.specifiers.length === 0) {
|
|
1645
|
+
return null;
|
|
1646
|
+
}
|
|
1647
|
+
return node;
|
|
1648
|
+
}
|
|
1649
|
+
throw new Error(`Unknown export node type: ${node.type}`);
|
|
1650
|
+
}).filter((node) => node !== null);
|
|
1651
|
+
return generate(ast, generateOptions);
|
|
1652
|
+
}
|
|
1653
|
+
);
|
|
1654
|
+
}
|
|
1655
|
+
function omitChunkedExports(code, exportNames, generateOptions = {}, cache, cacheKey) {
|
|
1656
|
+
return getOrSetFromCache(
|
|
1657
|
+
cache,
|
|
1658
|
+
`${cacheKey}::omitChunkedExports::${exportNames.join(
|
|
1659
|
+
","
|
|
1660
|
+
)}::${JSON.stringify(generateOptions)}`,
|
|
1661
|
+
code,
|
|
1662
|
+
() => {
|
|
1663
|
+
const isChunkable = (exportName) => hasChunkableExport(code, exportName, cache, cacheKey);
|
|
1664
|
+
const isOmitted = (exportName) => exportNames.includes(exportName) && isChunkable(exportName);
|
|
1665
|
+
const isRetained = (exportName) => !isOmitted(exportName);
|
|
1666
|
+
let exportDependencies = getExportDependencies(code, cache, cacheKey);
|
|
1667
|
+
let allExportNames = Array.from(exportDependencies.keys());
|
|
1668
|
+
let omittedExportNames = allExportNames.filter(isOmitted);
|
|
1669
|
+
let retainedExportNames = allExportNames.filter(isRetained);
|
|
1670
|
+
let omittedStatements = /* @__PURE__ */ new Set();
|
|
1671
|
+
let omittedExportedVariableDeclarators = /* @__PURE__ */ new Set();
|
|
1672
|
+
for (let omittedExportName of omittedExportNames) {
|
|
1673
|
+
let dependencies = exportDependencies.get(omittedExportName);
|
|
1674
|
+
invariant(
|
|
1675
|
+
dependencies,
|
|
1676
|
+
`Expected dependencies for ${omittedExportName}`
|
|
1677
|
+
);
|
|
1678
|
+
for (let statement of dependencies.topLevelNonModuleStatements) {
|
|
1679
|
+
omittedStatements.add(statement);
|
|
1680
|
+
}
|
|
1681
|
+
for (let declarator of dependencies.exportedVariableDeclarators) {
|
|
1682
|
+
omittedExportedVariableDeclarators.add(declarator);
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
let ast = codeToAst(code, cache, cacheKey);
|
|
1686
|
+
let omittedStatementsArray = Array.from(omittedStatements);
|
|
1687
|
+
let omittedExportedVariableDeclaratorsArray = Array.from(
|
|
1688
|
+
omittedExportedVariableDeclarators
|
|
1689
|
+
);
|
|
1690
|
+
ast.program.body = ast.program.body.filter(
|
|
1691
|
+
(node) => omittedStatementsArray.every(
|
|
1692
|
+
(statement) => !t.isNodesEquivalent(node, statement)
|
|
1693
|
+
)
|
|
1694
|
+
).map((node) => {
|
|
1695
|
+
if (!t.isImportDeclaration(node)) {
|
|
1696
|
+
return node;
|
|
1697
|
+
}
|
|
1698
|
+
if (node.specifiers.length === 0) {
|
|
1699
|
+
return node;
|
|
1700
|
+
}
|
|
1701
|
+
node.specifiers = node.specifiers.filter((specifier) => {
|
|
1702
|
+
let importedName = specifier.local.name;
|
|
1703
|
+
for (let retainedExportName of retainedExportNames) {
|
|
1704
|
+
let dependencies = exportDependencies.get(retainedExportName);
|
|
1705
|
+
if (dependencies?.importedIdentifierNames?.has(importedName)) {
|
|
1706
|
+
return true;
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
for (let omittedExportName of omittedExportNames) {
|
|
1710
|
+
let dependencies = exportDependencies.get(omittedExportName);
|
|
1711
|
+
if (dependencies?.importedIdentifierNames?.has(importedName)) {
|
|
1712
|
+
return false;
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
return true;
|
|
1716
|
+
});
|
|
1717
|
+
if (node.specifiers.length === 0) {
|
|
1718
|
+
return null;
|
|
1719
|
+
}
|
|
1720
|
+
return node;
|
|
1721
|
+
}).map((node) => {
|
|
1722
|
+
if (!t.isExportDeclaration(node)) {
|
|
1723
|
+
return node;
|
|
1724
|
+
}
|
|
1725
|
+
if (t.isExportAllDeclaration(node)) {
|
|
1726
|
+
return node;
|
|
1727
|
+
}
|
|
1728
|
+
if (t.isExportDefaultDeclaration(node)) {
|
|
1729
|
+
return isOmitted("default") ? null : node;
|
|
1730
|
+
}
|
|
1731
|
+
if (t.isVariableDeclaration(node.declaration)) {
|
|
1732
|
+
node.declaration.declarations = node.declaration.declarations.filter(
|
|
1733
|
+
(node2) => omittedExportedVariableDeclaratorsArray.every(
|
|
1734
|
+
(declarator) => !t.isNodesEquivalent(node2, declarator)
|
|
1735
|
+
)
|
|
1736
|
+
);
|
|
1737
|
+
if (node.declaration.declarations.length === 0) {
|
|
1738
|
+
return null;
|
|
1739
|
+
}
|
|
1740
|
+
return node;
|
|
1741
|
+
}
|
|
1742
|
+
if (t.isFunctionDeclaration(node.declaration) || t.isClassDeclaration(node.declaration)) {
|
|
1743
|
+
invariant(
|
|
1744
|
+
node.declaration.id,
|
|
1745
|
+
"Expected exported function or class declaration to have a name when not the default export"
|
|
1746
|
+
);
|
|
1747
|
+
return isOmitted(node.declaration.id.name) ? null : node;
|
|
1748
|
+
}
|
|
1749
|
+
if (t.isExportNamedDeclaration(node)) {
|
|
1750
|
+
if (node.specifiers.length === 0) {
|
|
1751
|
+
return node;
|
|
1752
|
+
}
|
|
1753
|
+
node.specifiers = node.specifiers.filter((specifier) => {
|
|
1754
|
+
const exportedName = getExportedName(specifier.exported);
|
|
1755
|
+
return !isOmitted(exportedName);
|
|
1756
|
+
});
|
|
1757
|
+
if (node.specifiers.length === 0) {
|
|
1758
|
+
return null;
|
|
1759
|
+
}
|
|
1760
|
+
return node;
|
|
1761
|
+
}
|
|
1762
|
+
throw new Error(`Unknown node type: ${node.type}`);
|
|
1763
|
+
}).filter((node) => node !== null);
|
|
1764
|
+
if (ast.program.body.length === 0) {
|
|
1765
|
+
return void 0;
|
|
1766
|
+
}
|
|
1767
|
+
return generate(ast, generateOptions);
|
|
1768
|
+
}
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
1771
|
+
function detectRouteChunks(code, cache, cacheKey) {
|
|
1772
|
+
const hasRouteChunkByExportName = Object.fromEntries(
|
|
1773
|
+
routeChunkExportNames.map((exportName) => [
|
|
1774
|
+
exportName,
|
|
1775
|
+
hasChunkableExport(code, exportName, cache, cacheKey)
|
|
1776
|
+
])
|
|
1777
|
+
);
|
|
1778
|
+
const chunkedExports = Object.entries(hasRouteChunkByExportName).filter(([, isChunked]) => isChunked).map(([exportName]) => exportName);
|
|
1779
|
+
const hasRouteChunks = chunkedExports.length > 0;
|
|
1780
|
+
return {
|
|
1781
|
+
hasRouteChunks,
|
|
1782
|
+
hasRouteChunkByExportName,
|
|
1783
|
+
chunkedExports
|
|
1784
|
+
};
|
|
1785
|
+
}
|
|
1786
|
+
var routeChunkExportNames = [
|
|
1787
|
+
"clientAction",
|
|
1788
|
+
"clientLoader",
|
|
1789
|
+
"HydrateFallback"
|
|
1790
|
+
];
|
|
1791
|
+
var mainChunkName = "main";
|
|
1792
|
+
var routeChunkNames = ["main", ...routeChunkExportNames];
|
|
1793
|
+
function getRouteChunkCode(code, chunkName, cache, cacheKey) {
|
|
1794
|
+
if (chunkName === mainChunkName) {
|
|
1795
|
+
return omitChunkedExports(code, routeChunkExportNames, {}, cache, cacheKey);
|
|
1796
|
+
}
|
|
1797
|
+
return getChunkedExport(code, chunkName, {}, cache, cacheKey);
|
|
1798
|
+
}
|
|
1799
|
+
var routeChunkQueryStringPrefix = "?route-chunk=";
|
|
1800
|
+
var routeChunkQueryStrings = {
|
|
1801
|
+
main: `${routeChunkQueryStringPrefix}main`,
|
|
1802
|
+
clientAction: `${routeChunkQueryStringPrefix}clientAction`,
|
|
1803
|
+
clientLoader: `${routeChunkQueryStringPrefix}clientLoader`,
|
|
1804
|
+
HydrateFallback: `${routeChunkQueryStringPrefix}HydrateFallback`
|
|
1805
|
+
};
|
|
1806
|
+
function getRouteChunkModuleId(filePath, chunkName) {
|
|
1807
|
+
return `${filePath}${routeChunkQueryStrings[chunkName]}`;
|
|
1808
|
+
}
|
|
1809
|
+
function isRouteChunkModuleId(id) {
|
|
1810
|
+
return Object.values(routeChunkQueryStrings).some(
|
|
1811
|
+
(queryString) => id.endsWith(queryString)
|
|
1812
|
+
);
|
|
1813
|
+
}
|
|
1814
|
+
function isRouteChunkName(name) {
|
|
1815
|
+
return name === mainChunkName || routeChunkExportNames.includes(name);
|
|
1816
|
+
}
|
|
1817
|
+
function getRouteChunkNameFromModuleId(id) {
|
|
1818
|
+
if (!isRouteChunkModuleId(id)) {
|
|
1819
|
+
return null;
|
|
1820
|
+
}
|
|
1821
|
+
let chunkName = id.split(routeChunkQueryStringPrefix)[1].split("&")[0];
|
|
1822
|
+
if (!isRouteChunkName(chunkName)) {
|
|
1823
|
+
return null;
|
|
1824
|
+
}
|
|
1825
|
+
return chunkName;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1162
1828
|
// vite/with-props.ts
|
|
1163
|
-
var
|
|
1829
|
+
var import_dedent3 = __toESM(require("dedent"));
|
|
1164
1830
|
var vmod = create("with-props");
|
|
1165
1831
|
var NAMED_COMPONENT_EXPORTS = ["HydrateFallback", "ErrorBoundary"];
|
|
1166
1832
|
var plugin = {
|
|
@@ -1171,7 +1837,7 @@ var plugin = {
|
|
|
1171
1837
|
},
|
|
1172
1838
|
async load(id) {
|
|
1173
1839
|
if (id !== vmod.resolvedId) return;
|
|
1174
|
-
return
|
|
1840
|
+
return import_dedent3.default`
|
|
1175
1841
|
import { createElement as h } from "react";
|
|
1176
1842
|
import { useActionData, useLoaderData, useMatches, useParams, useRouteError } from "react-router";
|
|
1177
1843
|
|
|
@@ -1191,6 +1857,8 @@ var plugin = {
|
|
|
1191
1857
|
return function Wrapped() {
|
|
1192
1858
|
const props = {
|
|
1193
1859
|
params: useParams(),
|
|
1860
|
+
loaderData: useLoaderData(),
|
|
1861
|
+
actionData: useActionData(),
|
|
1194
1862
|
};
|
|
1195
1863
|
return h(HydrateFallback, props);
|
|
1196
1864
|
};
|
|
@@ -1298,8 +1966,34 @@ var CLIENT_ROUTE_EXPORTS = [
|
|
|
1298
1966
|
"shouldRevalidate"
|
|
1299
1967
|
];
|
|
1300
1968
|
var BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
|
|
1969
|
+
var SSR_BUNDLE_PREFIX = "ssrBundle_";
|
|
1970
|
+
function isSeverBundleEnvironmentName(name) {
|
|
1971
|
+
return name.startsWith(SSR_BUNDLE_PREFIX);
|
|
1972
|
+
}
|
|
1973
|
+
function getServerEnvironmentEntries(record, buildManifest) {
|
|
1974
|
+
return Object.entries(record).filter(
|
|
1975
|
+
([name]) => buildManifest.serverBundles ? isSeverBundleEnvironmentName(name) : name === "ssr"
|
|
1976
|
+
);
|
|
1977
|
+
}
|
|
1978
|
+
function getServerEnvironmentValues(record, buildManifest) {
|
|
1979
|
+
return getServerEnvironmentEntries(record, buildManifest).map(
|
|
1980
|
+
([, value]) => value
|
|
1981
|
+
);
|
|
1982
|
+
}
|
|
1983
|
+
var isRouteEntryModuleId = (id) => {
|
|
1984
|
+
return id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING);
|
|
1985
|
+
};
|
|
1986
|
+
var isRouteVirtualModule = (id) => {
|
|
1987
|
+
return isRouteEntryModuleId(id) || isRouteChunkModuleId(id);
|
|
1988
|
+
};
|
|
1301
1989
|
var virtualHmrRuntime = create("hmr-runtime");
|
|
1302
1990
|
var virtualInjectHmrRuntime = create("inject-hmr-runtime");
|
|
1991
|
+
var normalizeRelativeFilePath = (file, reactRouterConfig) => {
|
|
1992
|
+
let vite2 = getVite();
|
|
1993
|
+
let fullPath = path6.resolve(reactRouterConfig.appDirectory, file);
|
|
1994
|
+
let relativePath = path6.relative(reactRouterConfig.appDirectory, fullPath);
|
|
1995
|
+
return vite2.normalizePath(relativePath).split("?")[0];
|
|
1996
|
+
};
|
|
1303
1997
|
var resolveRelativeRouteFilePath = (route, reactRouterConfig) => {
|
|
1304
1998
|
let vite2 = getVite();
|
|
1305
1999
|
let file = route.file;
|
|
@@ -1328,23 +2022,35 @@ var resolveChunk = (ctx, viteManifest, absoluteFilePath) => {
|
|
|
1328
2022
|
let rootRelativeFilePath = vite2.normalizePath(
|
|
1329
2023
|
path6.relative(ctx.rootDirectory, absoluteFilePath)
|
|
1330
2024
|
);
|
|
1331
|
-
let entryChunk = viteManifest[rootRelativeFilePath
|
|
2025
|
+
let entryChunk = viteManifest[rootRelativeFilePath];
|
|
1332
2026
|
if (!entryChunk) {
|
|
1333
|
-
|
|
1334
|
-
throw new Error(
|
|
1335
|
-
`No manifest entry found for "${rootRelativeFilePath}". Known manifest keys: ${knownManifestKeys}`
|
|
1336
|
-
);
|
|
2027
|
+
return void 0;
|
|
1337
2028
|
}
|
|
1338
2029
|
return entryChunk;
|
|
1339
2030
|
};
|
|
2031
|
+
var getPublicModulePathForEntry = (ctx, viteManifest, entryFilePath) => {
|
|
2032
|
+
let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
|
|
2033
|
+
return entryChunk ? `${ctx.publicPath}${entryChunk.file}` : void 0;
|
|
2034
|
+
};
|
|
1340
2035
|
var getReactRouterManifestBuildAssets = (ctx, viteManifest, entryFilePath, prependedAssetFilePaths = []) => {
|
|
1341
2036
|
let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
2037
|
+
invariant(entryChunk, "Chunk not found");
|
|
2038
|
+
let prependedAssetChunks = prependedAssetFilePaths.map((filePath) => {
|
|
2039
|
+
let chunk = resolveChunk(ctx, viteManifest, filePath);
|
|
2040
|
+
invariant(chunk, "Chunk not found");
|
|
2041
|
+
return chunk;
|
|
2042
|
+
});
|
|
2043
|
+
let routeModuleChunks = routeChunkNames.map(
|
|
2044
|
+
(routeChunkName) => resolveChunk(
|
|
2045
|
+
ctx,
|
|
2046
|
+
viteManifest,
|
|
2047
|
+
getRouteChunkModuleId(entryFilePath.split("?")[0], routeChunkName)
|
|
2048
|
+
)
|
|
2049
|
+
).filter(isNonNullable);
|
|
1345
2050
|
let chunks = resolveDependantChunks(viteManifest, [
|
|
1346
2051
|
...prependedAssetChunks,
|
|
1347
|
-
entryChunk
|
|
2052
|
+
entryChunk,
|
|
2053
|
+
...routeModuleChunks
|
|
1348
2054
|
]);
|
|
1349
2055
|
return {
|
|
1350
2056
|
module: `${ctx.publicPath}${entryChunk.file}`,
|
|
@@ -1381,6 +2087,10 @@ var writeFileSafe = async (file, contents) => {
|
|
|
1381
2087
|
await fse.ensureDir(path6.dirname(file));
|
|
1382
2088
|
await fse.writeFile(file, contents);
|
|
1383
2089
|
};
|
|
2090
|
+
var getExportNames = (code) => {
|
|
2091
|
+
let [, exportSpecifiers] = (0, import_es_module_lexer.parse)(code);
|
|
2092
|
+
return exportSpecifiers.map(({ n: name }) => name);
|
|
2093
|
+
};
|
|
1384
2094
|
var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
|
|
1385
2095
|
let entries = await Promise.all(
|
|
1386
2096
|
Object.entries(ctx.reactRouterConfig.routes).map(async ([key, route]) => {
|
|
@@ -1394,7 +2104,7 @@ var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
|
|
|
1394
2104
|
);
|
|
1395
2105
|
return Object.fromEntries(entries);
|
|
1396
2106
|
};
|
|
1397
|
-
var
|
|
2107
|
+
var compileRouteFile = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
|
|
1398
2108
|
if (!viteChildCompiler) {
|
|
1399
2109
|
throw new Error("Vite child compiler not found");
|
|
1400
2110
|
}
|
|
@@ -1414,20 +2124,38 @@ var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteF
|
|
|
1414
2124
|
moduleGraph.ensureEntryFromUrl(url2, ssr)
|
|
1415
2125
|
]);
|
|
1416
2126
|
let transformed = await pluginContainer.transform(code, id, { ssr });
|
|
1417
|
-
|
|
1418
|
-
let exportNames = exports2.map((e) => e.n);
|
|
1419
|
-
return exportNames;
|
|
2127
|
+
return transformed.code;
|
|
1420
2128
|
};
|
|
1421
|
-
var
|
|
1422
|
-
if (!
|
|
2129
|
+
var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
|
|
2130
|
+
if (!viteChildCompiler) {
|
|
2131
|
+
throw new Error("Vite child compiler not found");
|
|
2132
|
+
}
|
|
2133
|
+
let code = await compileRouteFile(
|
|
2134
|
+
viteChildCompiler,
|
|
2135
|
+
ctx,
|
|
2136
|
+
routeFile,
|
|
2137
|
+
readRouteFile
|
|
2138
|
+
);
|
|
2139
|
+
return getExportNames(code);
|
|
2140
|
+
};
|
|
2141
|
+
var resolveEnvironmentBuildContext = ({
|
|
2142
|
+
viteCommand,
|
|
2143
|
+
viteUserConfig
|
|
2144
|
+
}) => {
|
|
2145
|
+
if (!("__reactRouterEnvironmentBuildContext" in viteUserConfig) || !viteUserConfig.__reactRouterEnvironmentBuildContext) {
|
|
1423
2146
|
return null;
|
|
1424
2147
|
}
|
|
1425
|
-
|
|
2148
|
+
let buildContext = viteUserConfig.__reactRouterEnvironmentBuildContext;
|
|
2149
|
+
let resolvedBuildContext = {
|
|
2150
|
+
name: buildContext.name,
|
|
2151
|
+
options: buildContext.resolveOptions({ viteUserConfig })
|
|
2152
|
+
};
|
|
2153
|
+
return resolvedBuildContext;
|
|
1426
2154
|
};
|
|
1427
|
-
var getServerBuildDirectory = (ctx) => path6.join(
|
|
2155
|
+
var getServerBuildDirectory = (ctx, { serverBundleId } = {}) => path6.join(
|
|
1428
2156
|
ctx.reactRouterConfig.buildDirectory,
|
|
1429
2157
|
"server",
|
|
1430
|
-
...
|
|
2158
|
+
...serverBundleId ? [serverBundleId] : []
|
|
1431
2159
|
);
|
|
1432
2160
|
var getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
|
|
1433
2161
|
var defaultEntriesDir = path6.resolve(
|
|
@@ -1445,8 +2173,10 @@ var reactRouterVitePlugin = () => {
|
|
|
1445
2173
|
let viteUserConfig;
|
|
1446
2174
|
let viteConfigEnv;
|
|
1447
2175
|
let viteConfig;
|
|
2176
|
+
let buildManifest;
|
|
1448
2177
|
let cssModulesManifest = {};
|
|
1449
2178
|
let viteChildCompiler = null;
|
|
2179
|
+
let cache = /* @__PURE__ */ new Map();
|
|
1450
2180
|
let reactRouterConfigLoader;
|
|
1451
2181
|
let typegenWatcherPromise;
|
|
1452
2182
|
let logger;
|
|
@@ -1478,36 +2208,37 @@ var reactRouterVitePlugin = () => {
|
|
|
1478
2208
|
process.exit(1);
|
|
1479
2209
|
}
|
|
1480
2210
|
let viteManifestEnabled = viteUserConfig.build?.manifest === true;
|
|
1481
|
-
let
|
|
1482
|
-
isSsrBuild: true,
|
|
1483
|
-
getReactRouterServerManifest: async () => (await generateReactRouterManifestsForBuild()).reactRouterServerManifest,
|
|
1484
|
-
serverBundleBuildConfig: getServerBundleBuildConfig(viteUserConfig)
|
|
1485
|
-
} : { isSsrBuild: false };
|
|
2211
|
+
let environmentBuildContext = viteCommand === "build" ? resolveEnvironmentBuildContext({ viteCommand, viteUserConfig }) : null;
|
|
1486
2212
|
firstLoad = false;
|
|
1487
2213
|
ctx = {
|
|
2214
|
+
environmentBuildContext,
|
|
1488
2215
|
reactRouterConfig,
|
|
1489
2216
|
rootDirectory,
|
|
1490
2217
|
entryClientFilePath,
|
|
1491
2218
|
entryServerFilePath,
|
|
1492
2219
|
publicPath,
|
|
1493
|
-
viteManifestEnabled
|
|
1494
|
-
...ssrBuildCtx
|
|
2220
|
+
viteManifestEnabled
|
|
1495
2221
|
};
|
|
1496
2222
|
};
|
|
1497
2223
|
let pluginIndex = (pluginName) => {
|
|
1498
2224
|
invariant(viteConfig);
|
|
1499
2225
|
return viteConfig.plugins.findIndex((plugin2) => plugin2.name === pluginName);
|
|
1500
2226
|
};
|
|
1501
|
-
let getServerEntry = async () => {
|
|
2227
|
+
let getServerEntry = async ({ routeIds }) => {
|
|
1502
2228
|
invariant(viteConfig, "viteconfig required to generate the server entry");
|
|
1503
|
-
let routes =
|
|
2229
|
+
let routes = routeIds ? (
|
|
1504
2230
|
// For server bundle builds, the server build should only import the
|
|
1505
2231
|
// routes for this bundle rather than importing all routes
|
|
1506
|
-
ctx.
|
|
2232
|
+
(0, import_pick3.default)(ctx.reactRouterConfig.routes, routeIds)
|
|
1507
2233
|
) : (
|
|
1508
2234
|
// Otherwise, all routes are imported as usual
|
|
1509
2235
|
ctx.reactRouterConfig.routes
|
|
1510
2236
|
);
|
|
2237
|
+
let prerenderPaths = await getPrerenderPaths(
|
|
2238
|
+
ctx.reactRouterConfig.prerender,
|
|
2239
|
+
ctx.reactRouterConfig.ssr,
|
|
2240
|
+
routes
|
|
2241
|
+
);
|
|
1511
2242
|
return `
|
|
1512
2243
|
import * as entryServer from ${JSON.stringify(
|
|
1513
2244
|
resolveFileUrl(ctx, ctx.entryServerFilePath)
|
|
@@ -1522,7 +2253,7 @@ var reactRouterVitePlugin = () => {
|
|
|
1522
2253
|
)};`;
|
|
1523
2254
|
}).join("\n")}
|
|
1524
2255
|
export { default as assets } from ${JSON.stringify(
|
|
1525
|
-
virtual.serverManifest.id
|
|
2256
|
+
`${virtual.serverManifest.id}${routeIds ? `?route-ids=${routeIds.join(",")}` : ""}`
|
|
1526
2257
|
)};
|
|
1527
2258
|
export const assetsBuildDirectory = ${JSON.stringify(
|
|
1528
2259
|
path6.relative(
|
|
@@ -1532,7 +2263,9 @@ var reactRouterVitePlugin = () => {
|
|
|
1532
2263
|
)};
|
|
1533
2264
|
export const basename = ${JSON.stringify(ctx.reactRouterConfig.basename)};
|
|
1534
2265
|
export const future = ${JSON.stringify(ctx.reactRouterConfig.future)};
|
|
1535
|
-
export const
|
|
2266
|
+
export const ssr = ${ctx.reactRouterConfig.ssr};
|
|
2267
|
+
export const isSpaMode = ${isSpaModeEnabled(ctx.reactRouterConfig)};
|
|
2268
|
+
export const prerender = ${JSON.stringify(prerenderPaths)};
|
|
1536
2269
|
export const publicPath = ${JSON.stringify(ctx.publicPath)};
|
|
1537
2270
|
export const entry = { module: entryServer };
|
|
1538
2271
|
export const routes = {
|
|
@@ -1570,7 +2303,9 @@ var reactRouterVitePlugin = () => {
|
|
|
1570
2303
|
);
|
|
1571
2304
|
return /* @__PURE__ */ new Set([...cssUrlPaths, ...chunkAssetPaths]);
|
|
1572
2305
|
};
|
|
1573
|
-
let generateReactRouterManifestsForBuild = async (
|
|
2306
|
+
let generateReactRouterManifestsForBuild = async ({
|
|
2307
|
+
routeIds
|
|
2308
|
+
}) => {
|
|
1574
2309
|
invariant(viteConfig);
|
|
1575
2310
|
let viteManifest = await loadViteManifest(
|
|
1576
2311
|
getClientBuildDirectory(ctx.reactRouterConfig)
|
|
@@ -1586,13 +2321,31 @@ var reactRouterVitePlugin = () => {
|
|
|
1586
2321
|
viteChildCompiler,
|
|
1587
2322
|
ctx
|
|
1588
2323
|
);
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
);
|
|
1594
|
-
let sourceExports = routeManifestExports[key];
|
|
2324
|
+
let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
|
|
2325
|
+
for (let route of Object.values(ctx.reactRouterConfig.routes)) {
|
|
2326
|
+
let routeFile = path6.join(ctx.reactRouterConfig.appDirectory, route.file);
|
|
2327
|
+
let sourceExports = routeManifestExports[route.id];
|
|
1595
2328
|
let isRootRoute = route.parentId === void 0;
|
|
2329
|
+
let hasClientAction = sourceExports.includes("clientAction");
|
|
2330
|
+
let hasClientLoader = sourceExports.includes("clientLoader");
|
|
2331
|
+
let hasHydrateFallback = sourceExports.includes("HydrateFallback");
|
|
2332
|
+
let { hasRouteChunkByExportName } = await detectRouteChunksIfEnabled(
|
|
2333
|
+
cache,
|
|
2334
|
+
ctx,
|
|
2335
|
+
routeFile,
|
|
2336
|
+
{ routeFile, viteChildCompiler }
|
|
2337
|
+
);
|
|
2338
|
+
if (enforceSplitRouteModules) {
|
|
2339
|
+
validateRouteChunks({
|
|
2340
|
+
ctx,
|
|
2341
|
+
id: route.file,
|
|
2342
|
+
valid: {
|
|
2343
|
+
clientAction: !hasClientAction || hasRouteChunkByExportName.clientAction,
|
|
2344
|
+
clientLoader: !hasClientLoader || hasRouteChunkByExportName.clientLoader,
|
|
2345
|
+
HydrateFallback: !hasHydrateFallback || hasRouteChunkByExportName.HydrateFallback
|
|
2346
|
+
}
|
|
2347
|
+
});
|
|
2348
|
+
}
|
|
1596
2349
|
let routeManifestEntry = {
|
|
1597
2350
|
id: route.id,
|
|
1598
2351
|
parentId: route.parentId,
|
|
@@ -1601,23 +2354,37 @@ var reactRouterVitePlugin = () => {
|
|
|
1601
2354
|
caseSensitive: route.caseSensitive,
|
|
1602
2355
|
hasAction: sourceExports.includes("action"),
|
|
1603
2356
|
hasLoader: sourceExports.includes("loader"),
|
|
1604
|
-
hasClientAction
|
|
1605
|
-
hasClientLoader
|
|
2357
|
+
hasClientAction,
|
|
2358
|
+
hasClientLoader,
|
|
1606
2359
|
hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
|
|
1607
2360
|
...getReactRouterManifestBuildAssets(
|
|
1608
2361
|
ctx,
|
|
1609
2362
|
viteManifest,
|
|
1610
|
-
|
|
2363
|
+
`${routeFile}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
|
|
1611
2364
|
// If this is the root route, we also need to include assets from the
|
|
1612
2365
|
// client entry file as this is a common way for consumers to import
|
|
1613
2366
|
// global reset styles, etc.
|
|
1614
2367
|
isRootRoute ? [ctx.entryClientFilePath] : []
|
|
1615
|
-
)
|
|
2368
|
+
),
|
|
2369
|
+
clientActionModule: hasRouteChunkByExportName.clientAction ? getPublicModulePathForEntry(
|
|
2370
|
+
ctx,
|
|
2371
|
+
viteManifest,
|
|
2372
|
+
getRouteChunkModuleId(routeFile, "clientAction")
|
|
2373
|
+
) : void 0,
|
|
2374
|
+
clientLoaderModule: hasRouteChunkByExportName.clientLoader ? getPublicModulePathForEntry(
|
|
2375
|
+
ctx,
|
|
2376
|
+
viteManifest,
|
|
2377
|
+
getRouteChunkModuleId(routeFile, "clientLoader")
|
|
2378
|
+
) : void 0,
|
|
2379
|
+
hydrateFallbackModule: hasRouteChunkByExportName.HydrateFallback ? getPublicModulePathForEntry(
|
|
2380
|
+
ctx,
|
|
2381
|
+
viteManifest,
|
|
2382
|
+
getRouteChunkModuleId(routeFile, "HydrateFallback")
|
|
2383
|
+
) : void 0
|
|
1616
2384
|
};
|
|
1617
|
-
browserRoutes[
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
serverRoutes[key] = routeManifestEntry;
|
|
2385
|
+
browserRoutes[route.id] = routeManifestEntry;
|
|
2386
|
+
if (!routeIds || routeIds.includes(route.id)) {
|
|
2387
|
+
serverRoutes[route.id] = routeManifestEntry;
|
|
1621
2388
|
}
|
|
1622
2389
|
}
|
|
1623
2390
|
let fingerprintedValues = { entry, routes: browserRoutes };
|
|
@@ -1653,25 +2420,52 @@ var reactRouterVitePlugin = () => {
|
|
|
1653
2420
|
viteChildCompiler,
|
|
1654
2421
|
ctx
|
|
1655
2422
|
);
|
|
2423
|
+
let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
|
|
1656
2424
|
for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
|
|
2425
|
+
let routeFile = route.file;
|
|
1657
2426
|
let sourceExports = routeManifestExports[key];
|
|
2427
|
+
let hasClientAction = sourceExports.includes("clientAction");
|
|
2428
|
+
let hasClientLoader = sourceExports.includes("clientLoader");
|
|
2429
|
+
let hasHydrateFallback = sourceExports.includes("HydrateFallback");
|
|
2430
|
+
let routeModulePath = combineURLs(
|
|
2431
|
+
ctx.publicPath,
|
|
2432
|
+
`${resolveFileUrl(
|
|
2433
|
+
ctx,
|
|
2434
|
+
resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
2435
|
+
)}`
|
|
2436
|
+
);
|
|
2437
|
+
if (enforceSplitRouteModules) {
|
|
2438
|
+
let { hasRouteChunkByExportName } = await detectRouteChunksIfEnabled(
|
|
2439
|
+
cache,
|
|
2440
|
+
ctx,
|
|
2441
|
+
routeFile,
|
|
2442
|
+
{ routeFile, viteChildCompiler }
|
|
2443
|
+
);
|
|
2444
|
+
validateRouteChunks({
|
|
2445
|
+
ctx,
|
|
2446
|
+
id: route.file,
|
|
2447
|
+
valid: {
|
|
2448
|
+
clientAction: !hasClientAction || hasRouteChunkByExportName.clientAction,
|
|
2449
|
+
clientLoader: !hasClientLoader || hasRouteChunkByExportName.clientLoader,
|
|
2450
|
+
HydrateFallback: !hasHydrateFallback || hasRouteChunkByExportName.HydrateFallback
|
|
2451
|
+
}
|
|
2452
|
+
});
|
|
2453
|
+
}
|
|
1658
2454
|
routes[key] = {
|
|
1659
2455
|
id: route.id,
|
|
1660
2456
|
parentId: route.parentId,
|
|
1661
2457
|
path: route.path,
|
|
1662
2458
|
index: route.index,
|
|
1663
2459
|
caseSensitive: route.caseSensitive,
|
|
1664
|
-
module:
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
)
|
|
1670
|
-
),
|
|
2460
|
+
module: routeModulePath,
|
|
2461
|
+
// Split route modules are a build-time optimization
|
|
2462
|
+
clientActionModule: void 0,
|
|
2463
|
+
clientLoaderModule: void 0,
|
|
2464
|
+
hydrateFallbackModule: void 0,
|
|
1671
2465
|
hasAction: sourceExports.includes("action"),
|
|
1672
2466
|
hasLoader: sourceExports.includes("loader"),
|
|
1673
|
-
hasClientAction
|
|
1674
|
-
hasClientLoader
|
|
2467
|
+
hasClientAction,
|
|
2468
|
+
hasClientLoader,
|
|
1675
2469
|
hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
|
|
1676
2470
|
imports: []
|
|
1677
2471
|
};
|
|
@@ -1704,14 +2498,6 @@ var reactRouterVitePlugin = () => {
|
|
|
1704
2498
|
let viteClientConditions = [
|
|
1705
2499
|
...vite2.defaultClientConditions ?? []
|
|
1706
2500
|
];
|
|
1707
|
-
let packageRoot = path6.dirname(
|
|
1708
|
-
require.resolve("@react-router/dev/package.json")
|
|
1709
|
-
);
|
|
1710
|
-
let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
|
|
1711
|
-
let viteServerConditions = [
|
|
1712
|
-
...vite2.defaultServerConditions ?? [],
|
|
1713
|
-
...moduleSyncEnabled ? ["module-sync"] : []
|
|
1714
|
-
];
|
|
1715
2501
|
logger = vite2.createLogger(viteUserConfig.logLevel, {
|
|
1716
2502
|
prefix: "[react-router]"
|
|
1717
2503
|
});
|
|
@@ -1727,43 +2513,37 @@ var reactRouterVitePlugin = () => {
|
|
|
1727
2513
|
watch: viteCommand === "serve"
|
|
1728
2514
|
});
|
|
1729
2515
|
await updatePluginContext();
|
|
2516
|
+
buildManifest = await getBuildManifest(ctx);
|
|
1730
2517
|
Object.assign(
|
|
1731
2518
|
process.env,
|
|
1732
2519
|
vite2.loadEnv(
|
|
1733
2520
|
viteConfigEnv.mode,
|
|
1734
|
-
ctx.rootDirectory,
|
|
2521
|
+
viteUserConfig.envDir ?? ctx.rootDirectory,
|
|
1735
2522
|
// We override default prefix of "VITE_" with a blank string since
|
|
1736
2523
|
// we're targeting the server, so we want to load all environment
|
|
1737
2524
|
// variables, not just those explicitly marked for the client
|
|
1738
2525
|
""
|
|
1739
2526
|
)
|
|
1740
2527
|
);
|
|
1741
|
-
let
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
defaultHandler(warning);
|
|
1755
|
-
}
|
|
1756
|
-
}
|
|
1757
|
-
};
|
|
2528
|
+
let environments = await getEnvironmentsOptions(
|
|
2529
|
+
ctx,
|
|
2530
|
+
buildManifest,
|
|
2531
|
+
viteCommand,
|
|
2532
|
+
{ viteUserConfig }
|
|
2533
|
+
);
|
|
2534
|
+
let serverEnvironment = getServerEnvironmentValues(
|
|
2535
|
+
environments,
|
|
2536
|
+
buildManifest
|
|
2537
|
+
)[0];
|
|
2538
|
+
invariant(serverEnvironment);
|
|
2539
|
+
let clientEnvironment = environments.client;
|
|
2540
|
+
invariant(clientEnvironment);
|
|
1758
2541
|
return {
|
|
1759
2542
|
__reactRouterPluginContext: ctx,
|
|
1760
2543
|
appType: viteCommand === "serve" && viteConfigEnv.mode === "production" && ctx.reactRouterConfig.ssr === false ? "spa" : "custom",
|
|
1761
2544
|
ssr: {
|
|
1762
|
-
external:
|
|
1763
|
-
resolve:
|
|
1764
|
-
conditions: viteCommand === "build" ? viteServerConditions : ["development", ...viteServerConditions],
|
|
1765
|
-
externalConditions: viteCommand === "build" ? viteServerConditions : ["development", ...viteServerConditions]
|
|
1766
|
-
}
|
|
2545
|
+
external: serverEnvironment.resolve?.external,
|
|
2546
|
+
resolve: serverEnvironment.resolve
|
|
1767
2547
|
},
|
|
1768
2548
|
optimizeDeps: {
|
|
1769
2549
|
entries: ctx.reactRouterConfig.future.unstable_optimizeDeps ? [
|
|
@@ -1812,57 +2592,41 @@ var reactRouterVitePlugin = () => {
|
|
|
1812
2592
|
// will throw an error that the file is not allowed to be read.
|
|
1813
2593
|
// https://vitejs.dev/config/server-options#server-fs-allow
|
|
1814
2594
|
server: viteUserConfig.server?.fs?.allow ? { fs: { allow: defaultEntries } } : void 0,
|
|
1815
|
-
|
|
1816
|
-
|
|
2595
|
+
...ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? {
|
|
2596
|
+
environments,
|
|
1817
2597
|
build: {
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
// We need the manifest to detect SSR-only assets
|
|
1846
|
-
outDir: getServerBuildDirectory(ctx),
|
|
1847
|
-
rollupOptions: {
|
|
1848
|
-
...baseRollupOptions,
|
|
1849
|
-
preserveEntrySignatures: "exports-only",
|
|
1850
|
-
input: viteUserConfig.build?.rollupOptions?.input ?? virtual.serverBuild.id,
|
|
1851
|
-
output: {
|
|
1852
|
-
entryFileNames: ctx.reactRouterConfig.serverBuildFile,
|
|
1853
|
-
format: ctx.reactRouterConfig.serverModuleFormat
|
|
1854
|
-
}
|
|
1855
|
-
}
|
|
2598
|
+
// This isn't honored by the SSR environment config (which seems
|
|
2599
|
+
// to be a Vite bug?) so we set it here too.
|
|
2600
|
+
ssrEmitAssets: true
|
|
2601
|
+
},
|
|
2602
|
+
builder: {
|
|
2603
|
+
sharedConfigBuild: true,
|
|
2604
|
+
sharedPlugins: true,
|
|
2605
|
+
async buildApp(builder) {
|
|
2606
|
+
invariant(viteConfig);
|
|
2607
|
+
invariant(buildManifest);
|
|
2608
|
+
viteConfig.logger.info(
|
|
2609
|
+
"Using Vite Environment API (experimental)"
|
|
2610
|
+
);
|
|
2611
|
+
let { reactRouterConfig } = ctx;
|
|
2612
|
+
await cleanBuildDirectory(viteConfig, ctx);
|
|
2613
|
+
await builder.build(builder.environments.client);
|
|
2614
|
+
let serverEnvironments = getServerEnvironmentValues(
|
|
2615
|
+
builder.environments,
|
|
2616
|
+
buildManifest
|
|
2617
|
+
);
|
|
2618
|
+
await Promise.all(serverEnvironments.map(builder.build));
|
|
2619
|
+
await cleanViteManifests(environments, ctx);
|
|
2620
|
+
await reactRouterConfig.buildEnd?.({
|
|
2621
|
+
buildManifest,
|
|
2622
|
+
reactRouterConfig,
|
|
2623
|
+
viteConfig
|
|
2624
|
+
});
|
|
1856
2625
|
}
|
|
1857
2626
|
}
|
|
1858
|
-
} :
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
build: {
|
|
1862
|
-
manifest: true,
|
|
1863
|
-
outDir: getClientBuildDirectory(ctx.reactRouterConfig)
|
|
1864
|
-
}
|
|
1865
|
-
} : void 0
|
|
2627
|
+
} : {
|
|
2628
|
+
build: ctx.environmentBuildContext?.options.build ?? (viteConfigEnv.isSsrBuild ? serverEnvironment.build : clientEnvironment.build)
|
|
2629
|
+
}
|
|
1866
2630
|
};
|
|
1867
2631
|
},
|
|
1868
2632
|
async configResolved(resolvedViteConfig) {
|
|
@@ -1878,8 +2642,7 @@ var reactRouterVitePlugin = () => {
|
|
|
1878
2642
|
let childCompilerConfigFile = await vite2.loadConfigFromFile(
|
|
1879
2643
|
{
|
|
1880
2644
|
command: viteConfig.command,
|
|
1881
|
-
mode: viteConfig.mode
|
|
1882
|
-
isSsrBuild: ctx.isSsrBuild
|
|
2645
|
+
mode: viteConfig.mode
|
|
1883
2646
|
},
|
|
1884
2647
|
viteConfig.configFile
|
|
1885
2648
|
);
|
|
@@ -2021,14 +2784,15 @@ var reactRouterVitePlugin = () => {
|
|
|
2021
2784
|
// After the SSR build is finished, we inspect the Vite manifest for
|
|
2022
2785
|
// the SSR build and move server-only assets to client assets directory
|
|
2023
2786
|
async handler() {
|
|
2024
|
-
|
|
2787
|
+
let { future } = ctx.reactRouterConfig;
|
|
2788
|
+
if (future.unstable_viteEnvironmentApi ? this.environment.name === "client" : !viteConfigEnv.isSsrBuild) {
|
|
2025
2789
|
return;
|
|
2026
2790
|
}
|
|
2027
2791
|
invariant(viteConfig);
|
|
2028
2792
|
let clientBuildDirectory = getClientBuildDirectory(
|
|
2029
2793
|
ctx.reactRouterConfig
|
|
2030
2794
|
);
|
|
2031
|
-
let serverBuildDirectory = getServerBuildDirectory(ctx);
|
|
2795
|
+
let serverBuildDirectory = future.unstable_viteEnvironmentApi ? this.environment.config?.build?.outDir : ctx.environmentBuildContext?.options.build?.outDir ?? getServerBuildDirectory(ctx);
|
|
2032
2796
|
let ssrViteManifest = await loadViteManifest(serverBuildDirectory);
|
|
2033
2797
|
let ssrAssetPaths = getViteManifestAssetPaths(ssrViteManifest);
|
|
2034
2798
|
let movedAssetPaths = [];
|
|
@@ -2062,7 +2826,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2062
2826
|
].join("\n")
|
|
2063
2827
|
);
|
|
2064
2828
|
}
|
|
2065
|
-
if (ctx.reactRouterConfig
|
|
2829
|
+
if (isPrerenderingEnabled(ctx.reactRouterConfig)) {
|
|
2066
2830
|
await handlePrerender(
|
|
2067
2831
|
viteConfig,
|
|
2068
2832
|
ctx.reactRouterConfig,
|
|
@@ -2099,10 +2863,59 @@ var reactRouterVitePlugin = () => {
|
|
|
2099
2863
|
await typegenWatcher?.close();
|
|
2100
2864
|
}
|
|
2101
2865
|
},
|
|
2866
|
+
{
|
|
2867
|
+
name: "react-router:route-chunks-index",
|
|
2868
|
+
// This plugin provides the route module "index" since route modules can
|
|
2869
|
+
// be chunked and may be made up of multiple smaller modules. This plugin
|
|
2870
|
+
// primarily ensures code is never duplicated across a route module and
|
|
2871
|
+
// its chunks. If we didn't have this plugin, any app that explicitly
|
|
2872
|
+
// imports a route module would result in duplicate code since the app
|
|
2873
|
+
// would contain code for both the unprocessed route module as well as its
|
|
2874
|
+
// individual chunks. This is because, since they have different module
|
|
2875
|
+
// IDs, they are treated as completely separate modules even though they
|
|
2876
|
+
// all reference the same underlying file. This plugin addresses this by
|
|
2877
|
+
// ensuring that any explicit imports of a route module resolve to a
|
|
2878
|
+
// module that simply re-exports from its underlying chunks, if present.
|
|
2879
|
+
async transform(code, id, options) {
|
|
2880
|
+
if (viteCommand !== "build") return;
|
|
2881
|
+
if (options?.ssr) {
|
|
2882
|
+
return;
|
|
2883
|
+
}
|
|
2884
|
+
if (!isRoute(ctx.reactRouterConfig, id)) {
|
|
2885
|
+
return;
|
|
2886
|
+
}
|
|
2887
|
+
if (isRouteVirtualModule(id)) {
|
|
2888
|
+
return;
|
|
2889
|
+
}
|
|
2890
|
+
let { hasRouteChunks, chunkedExports } = await detectRouteChunksIfEnabled(cache, ctx, id, code);
|
|
2891
|
+
if (!hasRouteChunks) {
|
|
2892
|
+
return;
|
|
2893
|
+
}
|
|
2894
|
+
let sourceExports = await getRouteModuleExports(
|
|
2895
|
+
viteChildCompiler,
|
|
2896
|
+
ctx,
|
|
2897
|
+
id
|
|
2898
|
+
);
|
|
2899
|
+
let isMainChunkExport = (name) => !chunkedExports.includes(name);
|
|
2900
|
+
let mainChunkReexports = sourceExports.filter(isMainChunkExport).join(", ");
|
|
2901
|
+
let chunkBasePath = `./${path6.basename(id)}`;
|
|
2902
|
+
return [
|
|
2903
|
+
`export { ${mainChunkReexports} } from "${getRouteChunkModuleId(
|
|
2904
|
+
chunkBasePath,
|
|
2905
|
+
"main"
|
|
2906
|
+
)}";`,
|
|
2907
|
+
...chunkedExports.map(
|
|
2908
|
+
(exportName) => `export { ${exportName} } from "${getRouteChunkModuleId(
|
|
2909
|
+
chunkBasePath,
|
|
2910
|
+
exportName
|
|
2911
|
+
)}";`
|
|
2912
|
+
)
|
|
2913
|
+
].filter(Boolean).join("\n");
|
|
2914
|
+
}
|
|
2915
|
+
},
|
|
2102
2916
|
{
|
|
2103
2917
|
name: "react-router:build-client-route",
|
|
2104
|
-
|
|
2105
|
-
async transform(_code, id, options) {
|
|
2918
|
+
async transform(code, id, options) {
|
|
2106
2919
|
if (!id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING)) return;
|
|
2107
2920
|
let routeModuleId = id.replace(BUILD_CLIENT_ROUTE_QUERY_STRING, "");
|
|
2108
2921
|
let routeFileName = path6.basename(routeModuleId);
|
|
@@ -2111,26 +2924,91 @@ var reactRouterVitePlugin = () => {
|
|
|
2111
2924
|
ctx,
|
|
2112
2925
|
routeModuleId
|
|
2113
2926
|
);
|
|
2114
|
-
let
|
|
2115
|
-
|
|
2116
|
-
|
|
2927
|
+
let { chunkedExports = [] } = options?.ssr ? {} : await detectRouteChunksIfEnabled(cache, ctx, id, code);
|
|
2928
|
+
let reexports = sourceExports.filter((exportName) => {
|
|
2929
|
+
let isRouteEntryExport = options?.ssr && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS.includes(exportName);
|
|
2930
|
+
let isChunkedExport = chunkedExports.includes(
|
|
2931
|
+
exportName
|
|
2932
|
+
);
|
|
2933
|
+
return isRouteEntryExport && !isChunkedExport;
|
|
2934
|
+
}).join(", ");
|
|
2117
2935
|
return `export { ${reexports} } from "./${routeFileName}";`;
|
|
2118
2936
|
}
|
|
2119
2937
|
},
|
|
2938
|
+
{
|
|
2939
|
+
name: "react-router:split-route-modules",
|
|
2940
|
+
async transform(code, id, options) {
|
|
2941
|
+
if (options?.ssr) return;
|
|
2942
|
+
if (!isRouteChunkModuleId(id)) return;
|
|
2943
|
+
invariant(
|
|
2944
|
+
viteCommand === "build",
|
|
2945
|
+
"Route modules are only split in build mode"
|
|
2946
|
+
);
|
|
2947
|
+
let chunkName = getRouteChunkNameFromModuleId(id);
|
|
2948
|
+
if (!chunkName) {
|
|
2949
|
+
throw new Error(`Invalid route chunk name "${chunkName}" in "${id}"`);
|
|
2950
|
+
}
|
|
2951
|
+
let chunk = await getRouteChunkIfEnabled(
|
|
2952
|
+
cache,
|
|
2953
|
+
ctx,
|
|
2954
|
+
id,
|
|
2955
|
+
chunkName,
|
|
2956
|
+
code
|
|
2957
|
+
);
|
|
2958
|
+
let preventEmptyChunkSnippet = ({ reason }) => `Math.random()<0&&console.log(${JSON.stringify(reason)});`;
|
|
2959
|
+
if (chunk === null) {
|
|
2960
|
+
return preventEmptyChunkSnippet({
|
|
2961
|
+
reason: "Split round modules disabled"
|
|
2962
|
+
});
|
|
2963
|
+
}
|
|
2964
|
+
let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
|
|
2965
|
+
if (enforceSplitRouteModules && chunkName === "main" && chunk) {
|
|
2966
|
+
let exportNames = getExportNames(chunk.code);
|
|
2967
|
+
validateRouteChunks({
|
|
2968
|
+
ctx,
|
|
2969
|
+
id,
|
|
2970
|
+
valid: {
|
|
2971
|
+
clientAction: !exportNames.includes("clientAction"),
|
|
2972
|
+
clientLoader: !exportNames.includes("clientLoader"),
|
|
2973
|
+
HydrateFallback: !exportNames.includes("HydrateFallback")
|
|
2974
|
+
}
|
|
2975
|
+
});
|
|
2976
|
+
}
|
|
2977
|
+
return chunk ?? preventEmptyChunkSnippet({ reason: `No ${chunkName} chunk` });
|
|
2978
|
+
}
|
|
2979
|
+
},
|
|
2120
2980
|
{
|
|
2121
2981
|
name: "react-router:virtual-modules",
|
|
2122
2982
|
enforce: "pre",
|
|
2123
2983
|
resolveId(id) {
|
|
2124
|
-
|
|
2125
|
-
|
|
2984
|
+
let [baseId, queryString] = id.split("?");
|
|
2985
|
+
const vmod2 = Object.values(virtual).find((vmod3) => vmod3.id === baseId);
|
|
2986
|
+
if (vmod2)
|
|
2987
|
+
return vmod2.resolvedId + (queryString ? `?${queryString}` : "");
|
|
2126
2988
|
},
|
|
2127
2989
|
async load(id) {
|
|
2128
|
-
|
|
2990
|
+
let [baseId, queryString] = id.split("?");
|
|
2991
|
+
switch (baseId) {
|
|
2129
2992
|
case virtual.serverBuild.resolvedId: {
|
|
2130
|
-
|
|
2993
|
+
let searchParams = new URLSearchParams(queryString);
|
|
2994
|
+
let routeIds = searchParams.get("route-ids")?.split(",") || void 0;
|
|
2995
|
+
return await getServerEntry({ routeIds });
|
|
2131
2996
|
}
|
|
2132
2997
|
case virtual.serverManifest.resolvedId: {
|
|
2133
|
-
let
|
|
2998
|
+
let searchParams = new URLSearchParams(queryString);
|
|
2999
|
+
let routeIds = searchParams.get("route-ids")?.split(",") || void 0;
|
|
3000
|
+
let reactRouterManifest = viteCommand === "build" ? (await generateReactRouterManifestsForBuild({
|
|
3001
|
+
routeIds
|
|
3002
|
+
})).reactRouterServerManifest : await getReactRouterManifestForDev();
|
|
3003
|
+
if (!ctx.reactRouterConfig.ssr) {
|
|
3004
|
+
invariant(viteConfig);
|
|
3005
|
+
validateSsrFalsePrerenderExports(
|
|
3006
|
+
viteConfig,
|
|
3007
|
+
ctx,
|
|
3008
|
+
reactRouterManifest,
|
|
3009
|
+
viteChildCompiler
|
|
3010
|
+
);
|
|
3011
|
+
}
|
|
2134
3012
|
return `export default ${(0, import_jsesc.default)(reactRouterManifest, {
|
|
2135
3013
|
es6: true
|
|
2136
3014
|
})};`;
|
|
@@ -2171,8 +3049,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2171
3049
|
let importerShort = vite2.normalizePath(
|
|
2172
3050
|
path6.relative(ctx.rootDirectory, importer)
|
|
2173
3051
|
);
|
|
2174
|
-
|
|
2175
|
-
if (isRoute) {
|
|
3052
|
+
if (isRoute(ctx.reactRouterConfig, importer)) {
|
|
2176
3053
|
let serverOnlyExports = SERVER_ONLY_ROUTE_EXPORTS.map(
|
|
2177
3054
|
(xport) => `\`${xport}\``
|
|
2178
3055
|
).join(", ");
|
|
@@ -2211,10 +3088,10 @@ var reactRouterVitePlugin = () => {
|
|
|
2211
3088
|
let clientFileRE = /\.client(\.[cm]?[jt]sx?)?$/;
|
|
2212
3089
|
let clientDirRE = /\/\.client\//;
|
|
2213
3090
|
if (clientFileRE.test(id) || clientDirRE.test(id)) {
|
|
2214
|
-
let exports2 = (
|
|
3091
|
+
let exports2 = getExportNames(code);
|
|
2215
3092
|
return {
|
|
2216
3093
|
code: exports2.map(
|
|
2217
|
-
(
|
|
3094
|
+
(name) => name === "default" ? "export default undefined;" : `export const ${name} = undefined;`
|
|
2218
3095
|
).join("\n"),
|
|
2219
3096
|
map: null
|
|
2220
3097
|
};
|
|
@@ -2225,19 +3102,30 @@ var reactRouterVitePlugin = () => {
|
|
|
2225
3102
|
{
|
|
2226
3103
|
name: "react-router:route-exports",
|
|
2227
3104
|
async transform(code, id, options) {
|
|
3105
|
+
if (isRouteChunkModuleId(id)) {
|
|
3106
|
+
id = id.split("?")[0];
|
|
3107
|
+
}
|
|
2228
3108
|
let route = getRoute(ctx.reactRouterConfig, id);
|
|
2229
3109
|
if (!route) return;
|
|
2230
|
-
if (!options?.ssr &&
|
|
2231
|
-
let
|
|
3110
|
+
if (!options?.ssr && isSpaModeEnabled(ctx.reactRouterConfig)) {
|
|
3111
|
+
let exportNames = getExportNames(code);
|
|
3112
|
+
let serverOnlyExports = exportNames.filter((exp) => {
|
|
3113
|
+
if (route.id === "root" && exp === "loader") {
|
|
3114
|
+
return false;
|
|
3115
|
+
}
|
|
3116
|
+
return SERVER_ONLY_ROUTE_EXPORTS.includes(exp);
|
|
3117
|
+
});
|
|
2232
3118
|
if (serverOnlyExports.length > 0) {
|
|
2233
3119
|
let str = serverOnlyExports.map((e) => `\`${e}\``).join(", ");
|
|
2234
|
-
let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://
|
|
3120
|
+
let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://reactrouter.com/how-to/spa for more information.`;
|
|
2235
3121
|
throw Error(message);
|
|
2236
3122
|
}
|
|
2237
3123
|
if (route.id !== "root") {
|
|
2238
|
-
let hasHydrateFallback =
|
|
3124
|
+
let hasHydrateFallback = exportNames.some(
|
|
3125
|
+
(exp) => exp === "HydrateFallback"
|
|
3126
|
+
);
|
|
2239
3127
|
if (hasHydrateFallback) {
|
|
2240
|
-
let message = `SPA Mode: Invalid \`HydrateFallback\` export found in \`${route.file}\`. \`HydrateFallback\` is only permitted on the root route in SPA Mode. See https://
|
|
3128
|
+
let message = `SPA Mode: Invalid \`HydrateFallback\` export found in \`${route.file}\`. \`HydrateFallback\` is only permitted on the root route in SPA Mode. See https://reactrouter.com/how-to/spa for more information.`;
|
|
2241
3129
|
throw Error(message);
|
|
2242
3130
|
}
|
|
2243
3131
|
}
|
|
@@ -2248,7 +3136,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2248
3136
|
removeExports(ast, SERVER_ONLY_ROUTE_EXPORTS);
|
|
2249
3137
|
}
|
|
2250
3138
|
transform(ast);
|
|
2251
|
-
return
|
|
3139
|
+
return generate(ast, {
|
|
2252
3140
|
sourceMaps: true,
|
|
2253
3141
|
filename: id,
|
|
2254
3142
|
sourceFileName: filepath
|
|
@@ -2313,6 +3201,9 @@ var reactRouterVitePlugin = () => {
|
|
|
2313
3201
|
let isJSX = filepath.endsWith("x");
|
|
2314
3202
|
let useFastRefresh = !ssr && (isJSX || code.includes(devRuntime));
|
|
2315
3203
|
if (!useFastRefresh) return;
|
|
3204
|
+
if (isRouteVirtualModule(id)) {
|
|
3205
|
+
return { code: addRefreshWrapper(ctx.reactRouterConfig, code, id) };
|
|
3206
|
+
}
|
|
2316
3207
|
let result = await babel.transformAsync(code, {
|
|
2317
3208
|
babelrc: false,
|
|
2318
3209
|
configFile: false,
|
|
@@ -2343,6 +3234,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2343
3234
|
let serverManifest = (await server.ssrLoadModule(virtual.serverManifest.id)).default;
|
|
2344
3235
|
let oldRouteMetadata = serverManifest.routes[route.id];
|
|
2345
3236
|
let newRouteMetadata = await getRouteMetadata(
|
|
3237
|
+
cache,
|
|
2346
3238
|
ctx,
|
|
2347
3239
|
viteChildCompiler,
|
|
2348
3240
|
route,
|
|
@@ -2352,9 +3244,12 @@ var reactRouterVitePlugin = () => {
|
|
|
2352
3244
|
if (!oldRouteMetadata || [
|
|
2353
3245
|
"hasLoader",
|
|
2354
3246
|
"hasClientLoader",
|
|
3247
|
+
"clientLoaderModule",
|
|
2355
3248
|
"hasAction",
|
|
2356
3249
|
"hasClientAction",
|
|
2357
|
-
"
|
|
3250
|
+
"clientActionModule",
|
|
3251
|
+
"hasErrorBoundary",
|
|
3252
|
+
"hydrateFallbackModule"
|
|
2358
3253
|
].some((key) => oldRouteMetadata[key] !== newRouteMetadata[key])) {
|
|
2359
3254
|
invalidateVirtualModules(server);
|
|
2360
3255
|
}
|
|
@@ -2472,13 +3367,30 @@ function getRoute(pluginConfig, file) {
|
|
|
2472
3367
|
);
|
|
2473
3368
|
return route;
|
|
2474
3369
|
}
|
|
2475
|
-
|
|
3370
|
+
function isRoute(pluginConfig, file) {
|
|
3371
|
+
return Boolean(getRoute(pluginConfig, file));
|
|
3372
|
+
}
|
|
3373
|
+
async function getRouteMetadata(cache, ctx, viteChildCompiler, route, readRouteFile) {
|
|
3374
|
+
let routeFile = route.file;
|
|
2476
3375
|
let sourceExports = await getRouteModuleExports(
|
|
2477
3376
|
viteChildCompiler,
|
|
2478
3377
|
ctx,
|
|
2479
3378
|
route.file,
|
|
2480
3379
|
readRouteFile
|
|
2481
3380
|
);
|
|
3381
|
+
let { hasRouteChunkByExportName } = await detectRouteChunksIfEnabled(
|
|
3382
|
+
cache,
|
|
3383
|
+
ctx,
|
|
3384
|
+
routeFile,
|
|
3385
|
+
{ routeFile, readRouteFile, viteChildCompiler }
|
|
3386
|
+
);
|
|
3387
|
+
let moduleUrl = combineURLs(
|
|
3388
|
+
ctx.publicPath,
|
|
3389
|
+
`${resolveFileUrl(
|
|
3390
|
+
ctx,
|
|
3391
|
+
resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
3392
|
+
)}`
|
|
3393
|
+
);
|
|
2482
3394
|
let info = {
|
|
2483
3395
|
id: route.id,
|
|
2484
3396
|
parentId: route.parentId,
|
|
@@ -2492,14 +3404,11 @@ async function getRouteMetadata(ctx, viteChildCompiler, route, readRouteFile) {
|
|
|
2492
3404
|
resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
2493
3405
|
)
|
|
2494
3406
|
),
|
|
2495
|
-
module:
|
|
2496
|
-
ctx.publicPath,
|
|
2497
|
-
`${resolveFileUrl(
|
|
2498
|
-
ctx,
|
|
2499
|
-
resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
2500
|
-
)}?import`
|
|
2501
|
-
),
|
|
3407
|
+
module: `${moduleUrl}?import`,
|
|
2502
3408
|
// Ensure the Vite dev server responds with a JS module
|
|
3409
|
+
clientActionModule: hasRouteChunkByExportName.clientAction ? `${getRouteChunkModuleId(moduleUrl, "clientAction")}` : void 0,
|
|
3410
|
+
clientLoaderModule: hasRouteChunkByExportName.clientLoader ? `${getRouteChunkModuleId(moduleUrl, "clientLoader")}` : void 0,
|
|
3411
|
+
hydrateFallbackModule: hasRouteChunkByExportName.HydrateFallback ? `${getRouteChunkModuleId(moduleUrl, "HydrateFallback")}` : void 0,
|
|
2503
3412
|
hasAction: sourceExports.includes("action"),
|
|
2504
3413
|
hasClientAction: sourceExports.includes("clientAction"),
|
|
2505
3414
|
hasLoader: sourceExports.includes("loader"),
|
|
@@ -2509,6 +3418,12 @@ async function getRouteMetadata(ctx, viteChildCompiler, route, readRouteFile) {
|
|
|
2509
3418
|
};
|
|
2510
3419
|
return info;
|
|
2511
3420
|
}
|
|
3421
|
+
function isPrerenderingEnabled(reactRouterConfig) {
|
|
3422
|
+
return reactRouterConfig.prerender != null && reactRouterConfig.prerender !== false;
|
|
3423
|
+
}
|
|
3424
|
+
function isSpaModeEnabled(reactRouterConfig) {
|
|
3425
|
+
return reactRouterConfig.ssr === false && !isPrerenderingEnabled(reactRouterConfig);
|
|
3426
|
+
}
|
|
2512
3427
|
async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, serverBuildFile) {
|
|
2513
3428
|
let serverBuildPath = path6.join(serverBuildDirectory, serverBuildFile);
|
|
2514
3429
|
let build = await import(url.pathToFileURL(serverBuildPath).toString());
|
|
@@ -2519,20 +3434,49 @@ async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, ser
|
|
|
2519
3434
|
};
|
|
2520
3435
|
}
|
|
2521
3436
|
async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildFile, clientBuildDirectory) {
|
|
2522
|
-
let { handler } = await getPrerenderBuildAndHandler(
|
|
3437
|
+
let { build, handler } = await getPrerenderBuildAndHandler(
|
|
2523
3438
|
viteConfig,
|
|
2524
3439
|
serverBuildDirectory,
|
|
2525
3440
|
serverBuildFile
|
|
2526
3441
|
);
|
|
2527
|
-
let request = new Request(`http://localhost${reactRouterConfig.basename}
|
|
3442
|
+
let request = new Request(`http://localhost${reactRouterConfig.basename}`, {
|
|
3443
|
+
headers: {
|
|
3444
|
+
// Enable SPA mode in the server runtime and only render down to the root
|
|
3445
|
+
"X-React-Router-SPA-Mode": "yes"
|
|
3446
|
+
}
|
|
3447
|
+
});
|
|
2528
3448
|
let response = await handler(request);
|
|
2529
3449
|
let html = await response.text();
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
3450
|
+
let isPrerenderSpaFallback = build.prerender.includes("/");
|
|
3451
|
+
let filename3 = isPrerenderSpaFallback ? "__spa-fallback.html" : "index.html";
|
|
3452
|
+
if (response.status !== 200) {
|
|
3453
|
+
if (isPrerenderSpaFallback) {
|
|
3454
|
+
throw new Error(
|
|
3455
|
+
`Prerender: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename3}\` file.
|
|
3456
|
+
` + html
|
|
3457
|
+
);
|
|
3458
|
+
} else {
|
|
3459
|
+
throw new Error(
|
|
3460
|
+
`SPA Mode: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename3}\` file.
|
|
3461
|
+
` + html
|
|
3462
|
+
);
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
if (!html.includes("window.__reactRouterContext =") || !html.includes("window.__reactRouterRouteModules =")) {
|
|
3466
|
+
throw new Error(
|
|
3467
|
+
"SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`."
|
|
3468
|
+
);
|
|
3469
|
+
}
|
|
3470
|
+
await fse.writeFile(path6.join(clientBuildDirectory, filename3), html);
|
|
3471
|
+
let prettyDir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3472
|
+
let prettyPath = path6.join(prettyDir, filename3);
|
|
3473
|
+
if (build.prerender.length > 0) {
|
|
3474
|
+
viteConfig.logger.info(
|
|
3475
|
+
`Prerender (html): SPA Fallback -> ${import_picocolors3.default.bold(prettyPath)}`
|
|
3476
|
+
);
|
|
3477
|
+
} else {
|
|
3478
|
+
viteConfig.logger.info(`SPA Mode: Generated ${import_picocolors3.default.bold(prettyPath)}`);
|
|
3479
|
+
}
|
|
2536
3480
|
}
|
|
2537
3481
|
async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildPath, clientBuildDirectory) {
|
|
2538
3482
|
let { build, handler } = await getPrerenderBuildAndHandler(
|
|
@@ -2541,53 +3485,62 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
|
|
|
2541
3485
|
serverBuildPath
|
|
2542
3486
|
);
|
|
2543
3487
|
let routes = createPrerenderRoutes(build.routes);
|
|
2544
|
-
let routesToPrerender;
|
|
2545
|
-
if (typeof reactRouterConfig.prerender === "boolean") {
|
|
2546
|
-
invariant(reactRouterConfig.prerender, "Expected prerender:true");
|
|
2547
|
-
routesToPrerender = determineStaticPrerenderRoutes(
|
|
2548
|
-
routes,
|
|
2549
|
-
viteConfig,
|
|
2550
|
-
true
|
|
2551
|
-
);
|
|
2552
|
-
} else if (typeof reactRouterConfig.prerender === "function") {
|
|
2553
|
-
routesToPrerender = await reactRouterConfig.prerender({
|
|
2554
|
-
getStaticPaths: () => determineStaticPrerenderRoutes(routes, viteConfig, false)
|
|
2555
|
-
});
|
|
2556
|
-
} else {
|
|
2557
|
-
routesToPrerender = reactRouterConfig.prerender || ["/"];
|
|
2558
|
-
}
|
|
2559
3488
|
let headers = {
|
|
2560
3489
|
// Header that can be used in the loader to know if you're running at
|
|
2561
3490
|
// build time or runtime
|
|
2562
3491
|
"X-React-Router-Prerender": "yes"
|
|
2563
3492
|
};
|
|
2564
|
-
for (let path7 of
|
|
3493
|
+
for (let path7 of build.prerender) {
|
|
2565
3494
|
let matches = (0, import_react_router2.matchRoutes)(routes, `/${path7}/`.replace(/^\/\/+/, "/"));
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
handler,
|
|
2571
|
-
path7,
|
|
2572
|
-
clientBuildDirectory,
|
|
2573
|
-
reactRouterConfig,
|
|
2574
|
-
viteConfig,
|
|
2575
|
-
{ headers }
|
|
2576
|
-
);
|
|
2577
|
-
}
|
|
3495
|
+
invariant(
|
|
3496
|
+
matches,
|
|
3497
|
+
`Unable to prerender path because it does not match any routes: ${path7}`
|
|
3498
|
+
);
|
|
2578
3499
|
let leafRoute = matches ? matches[matches.length - 1].route : null;
|
|
2579
3500
|
let manifestRoute = leafRoute ? build.routes[leafRoute.id]?.module : null;
|
|
2580
|
-
let isResourceRoute = manifestRoute && !manifestRoute.default && !manifestRoute.ErrorBoundary
|
|
3501
|
+
let isResourceRoute = manifestRoute && !manifestRoute.default && !manifestRoute.ErrorBoundary;
|
|
2581
3502
|
if (isResourceRoute) {
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
3503
|
+
invariant(leafRoute);
|
|
3504
|
+
invariant(manifestRoute);
|
|
3505
|
+
if (manifestRoute.loader) {
|
|
3506
|
+
await prerenderData(
|
|
3507
|
+
handler,
|
|
3508
|
+
path7,
|
|
3509
|
+
[leafRoute.id],
|
|
3510
|
+
clientBuildDirectory,
|
|
3511
|
+
reactRouterConfig,
|
|
3512
|
+
viteConfig,
|
|
3513
|
+
{ headers }
|
|
3514
|
+
);
|
|
3515
|
+
await prerenderResourceRoute(
|
|
3516
|
+
handler,
|
|
3517
|
+
path7,
|
|
3518
|
+
clientBuildDirectory,
|
|
3519
|
+
reactRouterConfig,
|
|
3520
|
+
viteConfig,
|
|
3521
|
+
{ headers }
|
|
3522
|
+
);
|
|
3523
|
+
} else {
|
|
3524
|
+
viteConfig.logger.warn(
|
|
3525
|
+
`\u26A0\uFE0F Skipping prerendering for resource route without a loader: ${leafRoute?.id}`
|
|
3526
|
+
);
|
|
3527
|
+
}
|
|
2590
3528
|
} else {
|
|
3529
|
+
let hasLoaders = matches.some(
|
|
3530
|
+
(m) => build.assets.routes[m.route.id]?.hasLoader
|
|
3531
|
+
);
|
|
3532
|
+
let data;
|
|
3533
|
+
if (!isResourceRoute && hasLoaders) {
|
|
3534
|
+
data = await prerenderData(
|
|
3535
|
+
handler,
|
|
3536
|
+
path7,
|
|
3537
|
+
null,
|
|
3538
|
+
clientBuildDirectory,
|
|
3539
|
+
reactRouterConfig,
|
|
3540
|
+
viteConfig,
|
|
3541
|
+
{ headers }
|
|
3542
|
+
);
|
|
3543
|
+
}
|
|
2591
3544
|
await prerenderRoute(
|
|
2592
3545
|
handler,
|
|
2593
3546
|
path7,
|
|
@@ -2603,14 +3556,8 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
|
|
|
2603
3556
|
);
|
|
2604
3557
|
}
|
|
2605
3558
|
}
|
|
2606
|
-
await prerenderManifest(
|
|
2607
|
-
build,
|
|
2608
|
-
clientBuildDirectory,
|
|
2609
|
-
reactRouterConfig,
|
|
2610
|
-
viteConfig
|
|
2611
|
-
);
|
|
2612
3559
|
}
|
|
2613
|
-
function
|
|
3560
|
+
function getStaticPrerenderPaths(routes) {
|
|
2614
3561
|
let paths = ["/"];
|
|
2615
3562
|
let paramRoutes = [];
|
|
2616
3563
|
function recurse(subtree, prefix = "") {
|
|
@@ -2630,28 +3577,33 @@ function determineStaticPrerenderRoutes(routes, viteConfig, isBooleanUsage = fal
|
|
|
2630
3577
|
}
|
|
2631
3578
|
}
|
|
2632
3579
|
recurse(routes);
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
"You may want to use the `prerender()` API to prerender the following paths:",
|
|
2638
|
-
...paramRoutes.map((p) => " - " + p)
|
|
2639
|
-
].join("\n")
|
|
2640
|
-
);
|
|
2641
|
-
}
|
|
2642
|
-
return paths.map((p) => p.replace(/\/\/+/g, "/").replace(/(.+)\/$/, "$1"));
|
|
3580
|
+
return {
|
|
3581
|
+
paths: paths.map((p) => p.replace(/\/\/+/g, "/").replace(/(.+)\/$/, "$1")),
|
|
3582
|
+
paramRoutes
|
|
3583
|
+
};
|
|
2643
3584
|
}
|
|
2644
|
-
async function prerenderData(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
3585
|
+
async function prerenderData(handler, prerenderPath, onlyRoutes, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
2645
3586
|
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath === "/" ? "/_root.data" : `${prerenderPath.replace(/\/$/, "")}.data`}`.replace(/\/\/+/g, "/");
|
|
2646
|
-
let
|
|
3587
|
+
let url2 = new URL(`http://localhost${normalizedPath}`);
|
|
3588
|
+
if (onlyRoutes?.length) {
|
|
3589
|
+
url2.searchParams.set("_routes", onlyRoutes.join(","));
|
|
3590
|
+
}
|
|
3591
|
+
let request = new Request(url2, requestInit);
|
|
2647
3592
|
let response = await handler(request);
|
|
2648
3593
|
let data = await response.text();
|
|
2649
|
-
|
|
3594
|
+
if (response.status !== 200) {
|
|
3595
|
+
throw new Error(
|
|
3596
|
+
`Prerender (data): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${path6}\` path.
|
|
3597
|
+
${normalizedPath}`
|
|
3598
|
+
);
|
|
3599
|
+
}
|
|
2650
3600
|
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
2651
3601
|
let outfile = path6.join(outdir, ...normalizedPath.split("/"));
|
|
2652
3602
|
await fse.ensureDir(path6.dirname(outfile));
|
|
2653
3603
|
await fse.outputFile(outfile, data);
|
|
2654
|
-
viteConfig.logger.info(
|
|
3604
|
+
viteConfig.logger.info(
|
|
3605
|
+
`Prerender (data): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
3606
|
+
);
|
|
2655
3607
|
return data;
|
|
2656
3608
|
}
|
|
2657
3609
|
async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
@@ -2662,54 +3614,65 @@ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reac
|
|
|
2662
3614
|
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
2663
3615
|
let response = await handler(request);
|
|
2664
3616
|
let html = await response.text();
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
3617
|
+
if (response.status !== 200) {
|
|
3618
|
+
throw new Error(
|
|
3619
|
+
`Prerender (html): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.
|
|
3620
|
+
${html}`
|
|
3621
|
+
);
|
|
2668
3622
|
}
|
|
2669
3623
|
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
2670
3624
|
let outfile = path6.join(outdir, ...normalizedPath.split("/"), "index.html");
|
|
2671
3625
|
await fse.ensureDir(path6.dirname(outfile));
|
|
2672
3626
|
await fse.outputFile(outfile, html);
|
|
2673
|
-
viteConfig.logger.info(
|
|
3627
|
+
viteConfig.logger.info(
|
|
3628
|
+
`Prerender (html): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
3629
|
+
);
|
|
2674
3630
|
}
|
|
2675
3631
|
async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
2676
3632
|
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
|
|
2677
3633
|
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
2678
3634
|
let response = await handler(request);
|
|
2679
3635
|
let text = await response.text();
|
|
2680
|
-
|
|
3636
|
+
if (response.status !== 200) {
|
|
3637
|
+
throw new Error(
|
|
3638
|
+
`Prerender (resource): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.
|
|
3639
|
+
${text}`
|
|
3640
|
+
);
|
|
3641
|
+
}
|
|
2681
3642
|
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
2682
3643
|
let outfile = path6.join(outdir, ...normalizedPath.split("/"));
|
|
2683
3644
|
await fse.ensureDir(path6.dirname(outfile));
|
|
2684
3645
|
await fse.outputFile(outfile, text);
|
|
2685
|
-
viteConfig.logger.info(
|
|
2686
|
-
}
|
|
2687
|
-
async function prerenderManifest(build, clientBuildDirectory, reactRouterConfig, viteConfig) {
|
|
2688
|
-
let normalizedPath = `${reactRouterConfig.basename}/__manifest`.replace(
|
|
2689
|
-
/\/\/+/g,
|
|
2690
|
-
"/"
|
|
3646
|
+
viteConfig.logger.info(
|
|
3647
|
+
`Prerender (resource): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
2691
3648
|
);
|
|
2692
|
-
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
2693
|
-
let outfile = path6.join(outdir, ...normalizedPath.split("/"));
|
|
2694
|
-
await fse.ensureDir(path6.dirname(outfile));
|
|
2695
|
-
let manifestData = JSON.stringify(build.assets.routes);
|
|
2696
|
-
await fse.outputFile(outfile, manifestData);
|
|
2697
|
-
viteConfig.logger.info(`Prerender: Generated ${import_picocolors3.default.bold(outfile)}`);
|
|
2698
3649
|
}
|
|
2699
|
-
function
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
3650
|
+
async function getPrerenderPaths(prerender, ssr, routes, logWarning = false) {
|
|
3651
|
+
let prerenderPaths = [];
|
|
3652
|
+
if (prerender != null && prerender !== false) {
|
|
3653
|
+
let prerenderRoutes = createPrerenderRoutes(routes);
|
|
3654
|
+
if (prerender === true) {
|
|
3655
|
+
let { paths, paramRoutes } = getStaticPrerenderPaths(prerenderRoutes);
|
|
3656
|
+
if (logWarning && !ssr && paramRoutes.length > 0) {
|
|
3657
|
+
console.warn(
|
|
3658
|
+
import_picocolors3.default.yellow(
|
|
3659
|
+
[
|
|
3660
|
+
"\u26A0\uFE0F Paths with dynamic/splat params cannot be prerendered when using `prerender: true`. You may want to use the `prerender()` API to prerender the following paths:",
|
|
3661
|
+
...paramRoutes.map((p) => " - " + p)
|
|
3662
|
+
].join("\n")
|
|
3663
|
+
)
|
|
3664
|
+
);
|
|
3665
|
+
}
|
|
3666
|
+
prerenderPaths = paths;
|
|
3667
|
+
} else if (typeof prerender === "function") {
|
|
3668
|
+
prerenderPaths = await prerender({
|
|
3669
|
+
getStaticPaths: () => getStaticPrerenderPaths(prerenderRoutes).paths
|
|
3670
|
+
});
|
|
3671
|
+
} else {
|
|
3672
|
+
prerenderPaths = prerender || ["/"];
|
|
3673
|
+
}
|
|
2712
3674
|
}
|
|
3675
|
+
return prerenderPaths;
|
|
2713
3676
|
}
|
|
2714
3677
|
function groupRoutesByParentId2(manifest) {
|
|
2715
3678
|
let routes = {};
|
|
@@ -2727,24 +3690,445 @@ function groupRoutesByParentId2(manifest) {
|
|
|
2727
3690
|
function createPrerenderRoutes(manifest, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) {
|
|
2728
3691
|
return (routesByParentId[parentId] || []).map((route) => {
|
|
2729
3692
|
let commonRoute = {
|
|
2730
|
-
// Always include root due to default boundaries
|
|
2731
|
-
hasErrorBoundary: route.id === "root" || route.module.ErrorBoundary != null,
|
|
2732
3693
|
id: route.id,
|
|
2733
|
-
path: route.path
|
|
2734
|
-
loader: route.module.loader ? () => null : void 0,
|
|
2735
|
-
action: void 0,
|
|
2736
|
-
handle: route.module.handle
|
|
3694
|
+
path: route.path
|
|
2737
3695
|
};
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
3696
|
+
if (route.index) {
|
|
3697
|
+
return {
|
|
3698
|
+
index: true,
|
|
3699
|
+
...commonRoute
|
|
3700
|
+
};
|
|
3701
|
+
}
|
|
3702
|
+
return {
|
|
2743
3703
|
children: createPrerenderRoutes(manifest, route.id, routesByParentId),
|
|
2744
3704
|
...commonRoute
|
|
2745
3705
|
};
|
|
2746
3706
|
});
|
|
2747
3707
|
}
|
|
3708
|
+
async function validateSsrFalsePrerenderExports(viteConfig, ctx, manifest, viteChildCompiler) {
|
|
3709
|
+
let prerenderPaths = await getPrerenderPaths(
|
|
3710
|
+
ctx.reactRouterConfig.prerender,
|
|
3711
|
+
ctx.reactRouterConfig.ssr,
|
|
3712
|
+
manifest.routes,
|
|
3713
|
+
true
|
|
3714
|
+
);
|
|
3715
|
+
if (prerenderPaths.length === 0) {
|
|
3716
|
+
return;
|
|
3717
|
+
}
|
|
3718
|
+
let prerenderRoutes = createPrerenderRoutes(manifest.routes);
|
|
3719
|
+
let prerenderedRoutes = /* @__PURE__ */ new Set();
|
|
3720
|
+
for (let path7 of prerenderPaths) {
|
|
3721
|
+
let matches = (0, import_react_router2.matchRoutes)(
|
|
3722
|
+
prerenderRoutes,
|
|
3723
|
+
`/${path7}/`.replace(/^\/\/+/, "/")
|
|
3724
|
+
);
|
|
3725
|
+
invariant(
|
|
3726
|
+
matches,
|
|
3727
|
+
`Unable to prerender path because it does not match any routes: ${path7}`
|
|
3728
|
+
);
|
|
3729
|
+
matches.forEach((m) => prerenderedRoutes.add(m.route.id));
|
|
3730
|
+
}
|
|
3731
|
+
let errors = [];
|
|
3732
|
+
let routeExports = await getRouteManifestModuleExports(
|
|
3733
|
+
viteChildCompiler,
|
|
3734
|
+
ctx
|
|
3735
|
+
);
|
|
3736
|
+
for (let [routeId, route] of Object.entries(manifest.routes)) {
|
|
3737
|
+
let invalidApis = [];
|
|
3738
|
+
invariant(route, "Expected a route object in validateSsrFalseExports");
|
|
3739
|
+
let exports2 = routeExports[route.id];
|
|
3740
|
+
if (exports2.includes("headers")) invalidApis.push("headers");
|
|
3741
|
+
if (exports2.includes("action")) invalidApis.push("action");
|
|
3742
|
+
if (invalidApis.length > 0) {
|
|
3743
|
+
errors.push(
|
|
3744
|
+
`Prerender: ${invalidApis.length} invalid route export(s) in \`${route.id}\` when prerendering with \`ssr:false\`: ${invalidApis.join(", ")}. See https://reactrouter.com/how-to/pre-rendering for more information.`
|
|
3745
|
+
);
|
|
3746
|
+
}
|
|
3747
|
+
if (exports2.includes("loader") && !prerenderedRoutes.has(routeId)) {
|
|
3748
|
+
errors.push(
|
|
3749
|
+
`Prerender: 1 invalid route export in \`${route.id}\` when using \`ssr:false\` with \`prerender\` because the route is never prerendered so the loader will never be called. See https://reactrouter.com/how-to/pre-rendering for more information.`
|
|
3750
|
+
);
|
|
3751
|
+
}
|
|
3752
|
+
}
|
|
3753
|
+
if (errors.length > 0) {
|
|
3754
|
+
viteConfig.logger.error(import_picocolors3.default.red(errors.join("\n")));
|
|
3755
|
+
throw new Error(
|
|
3756
|
+
"Invalid route exports found when prerendering with `ssr:false`"
|
|
3757
|
+
);
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
function getAddressableRoutes(routes) {
|
|
3761
|
+
let nonAddressableIds = /* @__PURE__ */ new Set();
|
|
3762
|
+
for (let id in routes) {
|
|
3763
|
+
let route = routes[id];
|
|
3764
|
+
if (route.index) {
|
|
3765
|
+
invariant(
|
|
3766
|
+
route.parentId,
|
|
3767
|
+
`Expected index route "${route.id}" to have "parentId" set`
|
|
3768
|
+
);
|
|
3769
|
+
nonAddressableIds.add(route.parentId);
|
|
3770
|
+
}
|
|
3771
|
+
if (typeof route.path !== "string" && !route.index) {
|
|
3772
|
+
nonAddressableIds.add(id);
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
return Object.values(routes).filter(
|
|
3776
|
+
(route) => !nonAddressableIds.has(route.id)
|
|
3777
|
+
);
|
|
3778
|
+
}
|
|
3779
|
+
function getRouteBranch(routes, routeId) {
|
|
3780
|
+
let branch = [];
|
|
3781
|
+
let currentRouteId = routeId;
|
|
3782
|
+
while (currentRouteId) {
|
|
3783
|
+
let route = routes[currentRouteId];
|
|
3784
|
+
invariant(route, `Missing route for ${currentRouteId}`);
|
|
3785
|
+
branch.push(route);
|
|
3786
|
+
currentRouteId = route.parentId;
|
|
3787
|
+
}
|
|
3788
|
+
return branch.reverse();
|
|
3789
|
+
}
|
|
3790
|
+
function hasServerBundles(buildManifest) {
|
|
3791
|
+
return Object.keys(buildManifest.serverBundles ?? {}).length > 0;
|
|
3792
|
+
}
|
|
3793
|
+
function getRoutesByServerBundleId(buildManifest) {
|
|
3794
|
+
if (!buildManifest.routeIdToServerBundleId) {
|
|
3795
|
+
return {};
|
|
3796
|
+
}
|
|
3797
|
+
let routesByServerBundleId = {};
|
|
3798
|
+
for (let [routeId, serverBundleId] of Object.entries(
|
|
3799
|
+
buildManifest.routeIdToServerBundleId
|
|
3800
|
+
)) {
|
|
3801
|
+
routesByServerBundleId[serverBundleId] ??= {};
|
|
3802
|
+
let branch = getRouteBranch(buildManifest.routes, routeId);
|
|
3803
|
+
for (let route of branch) {
|
|
3804
|
+
routesByServerBundleId[serverBundleId][route.id] = route;
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
return routesByServerBundleId;
|
|
3808
|
+
}
|
|
3809
|
+
var resolveRouteFileCode = async (ctx, input) => {
|
|
3810
|
+
if (typeof input === "string") return input;
|
|
3811
|
+
invariant(input.viteChildCompiler);
|
|
3812
|
+
return await compileRouteFile(
|
|
3813
|
+
input.viteChildCompiler,
|
|
3814
|
+
ctx,
|
|
3815
|
+
input.routeFile,
|
|
3816
|
+
input.readRouteFile
|
|
3817
|
+
);
|
|
3818
|
+
};
|
|
3819
|
+
async function detectRouteChunksIfEnabled(cache, ctx, id, input) {
|
|
3820
|
+
function noRouteChunks() {
|
|
3821
|
+
return {
|
|
3822
|
+
chunkedExports: [],
|
|
3823
|
+
hasRouteChunks: false,
|
|
3824
|
+
hasRouteChunkByExportName: {
|
|
3825
|
+
clientAction: false,
|
|
3826
|
+
clientLoader: false,
|
|
3827
|
+
HydrateFallback: false
|
|
3828
|
+
}
|
|
3829
|
+
};
|
|
3830
|
+
}
|
|
3831
|
+
if (!ctx.reactRouterConfig.future.unstable_splitRouteModules) {
|
|
3832
|
+
return noRouteChunks();
|
|
3833
|
+
}
|
|
3834
|
+
if (normalizeRelativeFilePath(id, ctx.reactRouterConfig) === ctx.reactRouterConfig.routes.root.file) {
|
|
3835
|
+
return noRouteChunks();
|
|
3836
|
+
}
|
|
3837
|
+
let code = await resolveRouteFileCode(ctx, input);
|
|
3838
|
+
if (!routeChunkExportNames.some((exportName) => code.includes(exportName))) {
|
|
3839
|
+
return noRouteChunks();
|
|
3840
|
+
}
|
|
3841
|
+
let cacheKey = normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read");
|
|
3842
|
+
return detectRouteChunks(code, cache, cacheKey);
|
|
3843
|
+
}
|
|
3844
|
+
async function getRouteChunkIfEnabled(cache, ctx, id, chunkName, input) {
|
|
3845
|
+
if (!ctx.reactRouterConfig.future.unstable_splitRouteModules) {
|
|
3846
|
+
return null;
|
|
3847
|
+
}
|
|
3848
|
+
let code = await resolveRouteFileCode(ctx, input);
|
|
3849
|
+
let cacheKey = normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read");
|
|
3850
|
+
return getRouteChunkCode(code, chunkName, cache, cacheKey);
|
|
3851
|
+
}
|
|
3852
|
+
function validateRouteChunks({
|
|
3853
|
+
ctx,
|
|
3854
|
+
id,
|
|
3855
|
+
valid
|
|
3856
|
+
}) {
|
|
3857
|
+
let invalidChunks = Object.entries(valid).filter(([_, isValid]) => !isValid).map(([chunkName]) => chunkName);
|
|
3858
|
+
if (invalidChunks.length === 0) {
|
|
3859
|
+
return;
|
|
3860
|
+
}
|
|
3861
|
+
let plural = invalidChunks.length > 1;
|
|
3862
|
+
throw new Error(
|
|
3863
|
+
[
|
|
3864
|
+
`Error splitting route module: ${normalizeRelativeFilePath(
|
|
3865
|
+
id,
|
|
3866
|
+
ctx.reactRouterConfig
|
|
3867
|
+
)}`,
|
|
3868
|
+
invalidChunks.map((name) => `- ${name}`).join("\n"),
|
|
3869
|
+
`${plural ? "These exports" : "This export"} could not be split into ${plural ? "their own chunks" : "its own chunk"} because ${plural ? "they share" : "it shares"} code with other exports. You should extract any shared code into its own module and then import it within the route module.`
|
|
3870
|
+
].join("\n\n")
|
|
3871
|
+
);
|
|
3872
|
+
}
|
|
3873
|
+
async function cleanBuildDirectory(viteConfig, ctx) {
|
|
3874
|
+
let buildDirectory = ctx.reactRouterConfig.buildDirectory;
|
|
3875
|
+
let isWithinRoot = () => {
|
|
3876
|
+
let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
|
|
3877
|
+
return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
|
|
3878
|
+
};
|
|
3879
|
+
if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
|
|
3880
|
+
await fse.remove(buildDirectory);
|
|
3881
|
+
}
|
|
3882
|
+
}
|
|
3883
|
+
async function cleanViteManifests(environmentsOptions, ctx) {
|
|
3884
|
+
let viteManifestPaths = Object.entries(environmentsOptions).map(
|
|
3885
|
+
([environmentName, options]) => {
|
|
3886
|
+
let outDir = options.build?.outDir;
|
|
3887
|
+
invariant(outDir, `Expected build.outDir for ${environmentName}`);
|
|
3888
|
+
return path6.join(outDir, ".vite/manifest.json");
|
|
3889
|
+
}
|
|
3890
|
+
);
|
|
3891
|
+
await Promise.all(
|
|
3892
|
+
viteManifestPaths.map(async (viteManifestPath) => {
|
|
3893
|
+
let manifestExists = await fse.pathExists(viteManifestPath);
|
|
3894
|
+
if (!manifestExists) return;
|
|
3895
|
+
if (!ctx.viteManifestEnabled) {
|
|
3896
|
+
await fse.remove(viteManifestPath);
|
|
3897
|
+
}
|
|
3898
|
+
let viteDir = path6.dirname(viteManifestPath);
|
|
3899
|
+
let viteDirFiles = await fse.readdir(viteDir);
|
|
3900
|
+
if (viteDirFiles.length === 0) {
|
|
3901
|
+
await fse.remove(viteDir);
|
|
3902
|
+
}
|
|
3903
|
+
})
|
|
3904
|
+
);
|
|
3905
|
+
}
|
|
3906
|
+
async function getBuildManifest(ctx) {
|
|
3907
|
+
let { routes, serverBundles, appDirectory } = ctx.reactRouterConfig;
|
|
3908
|
+
if (!serverBundles) {
|
|
3909
|
+
return { routes };
|
|
3910
|
+
}
|
|
3911
|
+
let { normalizePath } = await import("vite");
|
|
3912
|
+
let serverBuildDirectory = getServerBuildDirectory(ctx);
|
|
3913
|
+
let resolvedAppDirectory = path6.resolve(ctx.rootDirectory, appDirectory);
|
|
3914
|
+
let rootRelativeRoutes = Object.fromEntries(
|
|
3915
|
+
Object.entries(routes).map(([id, route]) => {
|
|
3916
|
+
let filePath = path6.join(resolvedAppDirectory, route.file);
|
|
3917
|
+
let rootRelativeFilePath = normalizePath(
|
|
3918
|
+
path6.relative(ctx.rootDirectory, filePath)
|
|
3919
|
+
);
|
|
3920
|
+
return [id, { ...route, file: rootRelativeFilePath }];
|
|
3921
|
+
})
|
|
3922
|
+
);
|
|
3923
|
+
let buildManifest = {
|
|
3924
|
+
serverBundles: {},
|
|
3925
|
+
routeIdToServerBundleId: {},
|
|
3926
|
+
routes: rootRelativeRoutes
|
|
3927
|
+
};
|
|
3928
|
+
await Promise.all(
|
|
3929
|
+
getAddressableRoutes(routes).map(async (route) => {
|
|
3930
|
+
let branch = getRouteBranch(routes, route.id);
|
|
3931
|
+
let serverBundleId = await serverBundles({
|
|
3932
|
+
branch: branch.map(
|
|
3933
|
+
(route2) => configRouteToBranchRoute({
|
|
3934
|
+
...route2,
|
|
3935
|
+
// Ensure absolute paths are passed to the serverBundles function
|
|
3936
|
+
file: path6.join(resolvedAppDirectory, route2.file)
|
|
3937
|
+
})
|
|
3938
|
+
)
|
|
3939
|
+
});
|
|
3940
|
+
if (typeof serverBundleId !== "string") {
|
|
3941
|
+
throw new Error(`The "serverBundles" function must return a string`);
|
|
3942
|
+
}
|
|
3943
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(serverBundleId)) {
|
|
3944
|
+
throw new Error(
|
|
3945
|
+
`The "serverBundles" function must only return strings containing alphanumeric characters, hyphens and underscores.`
|
|
3946
|
+
);
|
|
3947
|
+
}
|
|
3948
|
+
buildManifest.routeIdToServerBundleId[route.id] = serverBundleId;
|
|
3949
|
+
buildManifest.serverBundles[serverBundleId] ??= {
|
|
3950
|
+
id: serverBundleId,
|
|
3951
|
+
file: normalizePath(
|
|
3952
|
+
path6.join(
|
|
3953
|
+
path6.relative(
|
|
3954
|
+
ctx.rootDirectory,
|
|
3955
|
+
path6.join(serverBuildDirectory, serverBundleId)
|
|
3956
|
+
),
|
|
3957
|
+
ctx.reactRouterConfig.serverBuildFile
|
|
3958
|
+
)
|
|
3959
|
+
)
|
|
3960
|
+
};
|
|
3961
|
+
})
|
|
3962
|
+
);
|
|
3963
|
+
return buildManifest;
|
|
3964
|
+
}
|
|
3965
|
+
function mergeEnvironmentOptions(base, ...overrides) {
|
|
3966
|
+
let vite2 = getVite();
|
|
3967
|
+
return overrides.reduce(
|
|
3968
|
+
(merged, override) => vite2.mergeConfig(merged, override, false),
|
|
3969
|
+
base
|
|
3970
|
+
);
|
|
3971
|
+
}
|
|
3972
|
+
async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
|
|
3973
|
+
let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
|
|
3974
|
+
let packageRoot = path6.dirname(
|
|
3975
|
+
require.resolve("@react-router/dev/package.json")
|
|
3976
|
+
);
|
|
3977
|
+
let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
|
|
3978
|
+
let vite2 = getVite();
|
|
3979
|
+
let viteServerConditions = [
|
|
3980
|
+
...vite2.defaultServerConditions ?? [],
|
|
3981
|
+
...moduleSyncEnabled ? ["module-sync"] : []
|
|
3982
|
+
];
|
|
3983
|
+
function getBaseOptions({
|
|
3984
|
+
viteUserConfig
|
|
3985
|
+
}) {
|
|
3986
|
+
return {
|
|
3987
|
+
build: {
|
|
3988
|
+
cssMinify: viteUserConfig.build?.cssMinify ?? true,
|
|
3989
|
+
manifest: true,
|
|
3990
|
+
// The manifest is enabled for all builds to detect SSR-only assets
|
|
3991
|
+
rollupOptions: {
|
|
3992
|
+
preserveEntrySignatures: "exports-only",
|
|
3993
|
+
// Silence Rollup "use client" warnings
|
|
3994
|
+
// Adapted from https://github.com/vitejs/vite-plugin-react/pull/144
|
|
3995
|
+
onwarn(warning, defaultHandler) {
|
|
3996
|
+
if (warning.code === "MODULE_LEVEL_DIRECTIVE" && warning.message.includes("use client")) {
|
|
3997
|
+
return;
|
|
3998
|
+
}
|
|
3999
|
+
let userHandler = viteUserConfig.build?.rollupOptions?.onwarn;
|
|
4000
|
+
if (userHandler) {
|
|
4001
|
+
userHandler(warning, defaultHandler);
|
|
4002
|
+
} else {
|
|
4003
|
+
defaultHandler(warning);
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
};
|
|
4009
|
+
}
|
|
4010
|
+
function getBaseServerOptions({
|
|
4011
|
+
viteUserConfig
|
|
4012
|
+
}) {
|
|
4013
|
+
let conditions = viteCommand === "build" ? viteServerConditions : ["development", ...viteServerConditions];
|
|
4014
|
+
return mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), {
|
|
4015
|
+
resolve: {
|
|
4016
|
+
external: ssrExternals,
|
|
4017
|
+
conditions,
|
|
4018
|
+
externalConditions: conditions
|
|
4019
|
+
},
|
|
4020
|
+
build: {
|
|
4021
|
+
// We move SSR-only assets to client assets. Note that the
|
|
4022
|
+
// SSR build can also emit code-split JS files (e.g. by
|
|
4023
|
+
// dynamic import) under the same assets directory
|
|
4024
|
+
// regardless of "ssrEmitAssets" option, so we also need to
|
|
4025
|
+
// keep these JS files have to be kept as-is.
|
|
4026
|
+
ssrEmitAssets: true,
|
|
4027
|
+
copyPublicDir: false,
|
|
4028
|
+
// Assets in the public directory are only used by the client
|
|
4029
|
+
rollupOptions: {
|
|
4030
|
+
output: {
|
|
4031
|
+
entryFileNames: serverBuildFile,
|
|
4032
|
+
format: serverModuleFormat
|
|
4033
|
+
}
|
|
4034
|
+
}
|
|
4035
|
+
}
|
|
4036
|
+
});
|
|
4037
|
+
}
|
|
4038
|
+
let environmentOptionsResolvers = {
|
|
4039
|
+
client: ({ viteUserConfig }) => mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), {
|
|
4040
|
+
build: {
|
|
4041
|
+
rollupOptions: {
|
|
4042
|
+
input: [
|
|
4043
|
+
ctx.entryClientFilePath,
|
|
4044
|
+
...Object.values(ctx.reactRouterConfig.routes).flatMap(
|
|
4045
|
+
(route) => {
|
|
4046
|
+
let routeFilePath = path6.resolve(
|
|
4047
|
+
ctx.reactRouterConfig.appDirectory,
|
|
4048
|
+
route.file
|
|
4049
|
+
);
|
|
4050
|
+
let isRootRoute = route.file === ctx.reactRouterConfig.routes.root.file;
|
|
4051
|
+
let code = fse.readFileSync(routeFilePath, "utf-8");
|
|
4052
|
+
return [
|
|
4053
|
+
`${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
|
|
4054
|
+
...ctx.reactRouterConfig.future.unstable_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
|
|
4055
|
+
(exportName) => code.includes(exportName) ? getRouteChunkModuleId(routeFilePath, exportName) : null
|
|
4056
|
+
) : []
|
|
4057
|
+
].filter(isNonNullable);
|
|
4058
|
+
}
|
|
4059
|
+
)
|
|
4060
|
+
],
|
|
4061
|
+
output: {
|
|
4062
|
+
entryFileNames({ moduleIds }) {
|
|
4063
|
+
let routeChunkModuleId = moduleIds.find(isRouteChunkModuleId);
|
|
4064
|
+
let routeChunkName = routeChunkModuleId ? getRouteChunkNameFromModuleId(routeChunkModuleId) : null;
|
|
4065
|
+
let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
|
|
4066
|
+
return `assets/[name]${routeChunkSuffix}-[hash].js`;
|
|
4067
|
+
}
|
|
4068
|
+
}
|
|
4069
|
+
},
|
|
4070
|
+
outDir: getClientBuildDirectory(ctx.reactRouterConfig)
|
|
4071
|
+
}
|
|
4072
|
+
})
|
|
4073
|
+
};
|
|
4074
|
+
if (hasServerBundles(buildManifest)) {
|
|
4075
|
+
for (let [serverBundleId, routes] of Object.entries(
|
|
4076
|
+
getRoutesByServerBundleId(buildManifest)
|
|
4077
|
+
)) {
|
|
4078
|
+
const serverBundleEnvironmentId = serverBundleId.replaceAll("-", "_");
|
|
4079
|
+
const environmentName = `${SSR_BUNDLE_PREFIX}${serverBundleEnvironmentId}`;
|
|
4080
|
+
environmentOptionsResolvers[environmentName] = ({ viteUserConfig }) => mergeEnvironmentOptions(
|
|
4081
|
+
getBaseServerOptions({ viteUserConfig }),
|
|
4082
|
+
{
|
|
4083
|
+
build: {
|
|
4084
|
+
outDir: getServerBuildDirectory(ctx, { serverBundleId }),
|
|
4085
|
+
rollupOptions: {
|
|
4086
|
+
input: `${virtual.serverBuild.id}?route-ids=${Object.keys(
|
|
4087
|
+
routes
|
|
4088
|
+
).join(",")}`
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
},
|
|
4092
|
+
// Ensure server bundle environments extend the user's SSR
|
|
4093
|
+
// environment config if it exists
|
|
4094
|
+
viteUserConfig.environments?.ssr ?? {}
|
|
4095
|
+
);
|
|
4096
|
+
}
|
|
4097
|
+
} else {
|
|
4098
|
+
environmentOptionsResolvers.ssr = ({ viteUserConfig }) => mergeEnvironmentOptions(getBaseServerOptions({ viteUserConfig }), {
|
|
4099
|
+
build: {
|
|
4100
|
+
outDir: getServerBuildDirectory(ctx),
|
|
4101
|
+
rollupOptions: {
|
|
4102
|
+
input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id
|
|
4103
|
+
}
|
|
4104
|
+
}
|
|
4105
|
+
});
|
|
4106
|
+
}
|
|
4107
|
+
return environmentOptionsResolvers;
|
|
4108
|
+
}
|
|
4109
|
+
function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
|
|
4110
|
+
let environmentOptions = {};
|
|
4111
|
+
for (let [environmentName, resolver] of Object.entries(
|
|
4112
|
+
environmentResolvers
|
|
4113
|
+
)) {
|
|
4114
|
+
environmentOptions[environmentName] = resolver(resolverOptions);
|
|
4115
|
+
}
|
|
4116
|
+
return environmentOptions;
|
|
4117
|
+
}
|
|
4118
|
+
async function getEnvironmentsOptions(ctx, buildManifest, viteCommand, resolverOptions) {
|
|
4119
|
+
let environmentOptionsResolvers = await getEnvironmentOptionsResolvers(
|
|
4120
|
+
ctx,
|
|
4121
|
+
buildManifest,
|
|
4122
|
+
viteCommand
|
|
4123
|
+
);
|
|
4124
|
+
return resolveEnvironmentsOptions(
|
|
4125
|
+
environmentOptionsResolvers,
|
|
4126
|
+
resolverOptions
|
|
4127
|
+
);
|
|
4128
|
+
}
|
|
4129
|
+
function isNonNullable(x) {
|
|
4130
|
+
return x != null;
|
|
4131
|
+
}
|
|
2748
4132
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2749
4133
|
0 && (module.exports = {
|
|
2750
4134
|
reactRouter
|