@react-router/dev 0.0.0-experimental-beaa4f52a → 0.0.0-experimental-df0f1dfda

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/dist/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-beaa4f52a
2
+ * @react-router/dev v0.0.0-experimental-df0f1dfda
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -443,7 +443,8 @@ async function resolveConfig({
443
443
  );
444
444
  }
445
445
  let future = {
446
- unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false
446
+ unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
447
+ unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false
447
448
  };
448
449
  let reactRouterConfig = deepFreeze({
449
450
  appDirectory,
@@ -692,8 +693,6 @@ function generate(ctx, route) {
692
693
  export type HeadersArgs = T.HeadersArgs
693
694
  export type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit
694
695
 
695
- export type MiddlewareArgs = T.CreateServerMiddlewareArgs<Info>
696
- export type ClientMiddlewareArgs = T.CreateClientMiddlewareArgs<Info>
697
696
  export type LoaderArgs = T.CreateServerLoaderArgs<Info>
698
697
  export type ClientLoaderArgs = T.CreateClientLoaderArgs<Info>
699
698
  export type ActionArgs = T.CreateServerActionArgs<Info>
@@ -1161,6 +1160,611 @@ function invalidDestructureError(name) {
1161
1160
  return new Error(`Cannot remove destructured export "${name}"`);
1162
1161
  }
1163
1162
 
1163
+ // vite/cache.ts
1164
+ function getOrSetFromCache(cache, key, version, getValue) {
1165
+ if (!cache) {
1166
+ return getValue();
1167
+ }
1168
+ let entry = cache.get(key);
1169
+ if (entry?.version === version) {
1170
+ return entry.value;
1171
+ }
1172
+ let value = getValue();
1173
+ let newEntry = { value, version };
1174
+ cache.set(key, newEntry);
1175
+ return value;
1176
+ }
1177
+
1178
+ // vite/route-chunks.ts
1179
+ function codeToAst(code, cache, cacheKey) {
1180
+ return structuredClone(
1181
+ getOrSetFromCache(
1182
+ cache,
1183
+ `${cacheKey}::codeToAst`,
1184
+ code,
1185
+ () => (0, import_parser.parse)(code, { sourceType: "module" })
1186
+ )
1187
+ );
1188
+ }
1189
+ function assertNodePath(path7) {
1190
+ invariant(
1191
+ path7 && !Array.isArray(path7),
1192
+ `Expected a Path, but got ${Array.isArray(path7) ? "an array" : path7}`
1193
+ );
1194
+ }
1195
+ function assertNodePathIsStatement(path7) {
1196
+ invariant(
1197
+ path7 && !Array.isArray(path7) && t.isStatement(path7.node),
1198
+ `Expected a Statement path, but got ${Array.isArray(path7) ? "an array" : path7?.node?.type}`
1199
+ );
1200
+ }
1201
+ function assertNodePathIsVariableDeclarator(path7) {
1202
+ invariant(
1203
+ path7 && !Array.isArray(path7) && t.isVariableDeclarator(path7.node),
1204
+ `Expected an Identifier path, but got ${Array.isArray(path7) ? "an array" : path7?.node?.type}`
1205
+ );
1206
+ }
1207
+ function assertNodePathIsPattern(path7) {
1208
+ invariant(
1209
+ path7 && !Array.isArray(path7) && t.isPattern(path7.node),
1210
+ `Expected a Pattern path, but got ${Array.isArray(path7) ? "an array" : path7?.node?.type}`
1211
+ );
1212
+ }
1213
+ function getExportDependencies(code, cache, cacheKey) {
1214
+ return getOrSetFromCache(
1215
+ cache,
1216
+ `${cacheKey}::getExportDependencies`,
1217
+ code,
1218
+ () => {
1219
+ let exportDependencies = /* @__PURE__ */ new Map();
1220
+ let ast = codeToAst(code, cache, cacheKey);
1221
+ function handleExport(exportName, exportPath, identifiersPath = exportPath) {
1222
+ let identifiers = getDependentIdentifiersForPath(identifiersPath);
1223
+ let topLevelStatements = /* @__PURE__ */ new Set([
1224
+ exportPath.node,
1225
+ ...getTopLevelStatementsForPaths(identifiers)
1226
+ ]);
1227
+ let topLevelNonModuleStatements = new Set(
1228
+ Array.from(topLevelStatements).filter(
1229
+ (statement) => !t.isImportDeclaration(statement) && !t.isExportDeclaration(statement)
1230
+ )
1231
+ );
1232
+ let importedIdentifierNames = /* @__PURE__ */ new Set();
1233
+ for (let identifier of identifiers) {
1234
+ if (identifier.parentPath.parentPath?.isImportDeclaration()) {
1235
+ importedIdentifierNames.add(identifier.node.name);
1236
+ }
1237
+ }
1238
+ let exportedVariableDeclarators = /* @__PURE__ */ new Set();
1239
+ for (let identifier of identifiers) {
1240
+ if (identifier.parentPath.isVariableDeclarator() && identifier.parentPath.parentPath.parentPath?.isExportNamedDeclaration()) {
1241
+ exportedVariableDeclarators.add(identifier.parentPath.node);
1242
+ continue;
1243
+ }
1244
+ let isWithinExportDestructuring = Boolean(
1245
+ identifier.findParent(
1246
+ (path7) => Boolean(
1247
+ path7.isPattern() && path7.parentPath?.isVariableDeclarator() && path7.parentPath.parentPath?.parentPath?.isExportNamedDeclaration()
1248
+ )
1249
+ )
1250
+ );
1251
+ if (isWithinExportDestructuring) {
1252
+ let currentPath = identifier;
1253
+ while (currentPath) {
1254
+ if (
1255
+ // Check the identifier is within a variable declaration, and if
1256
+ // so, ensure we're on the left-hand side of the expression
1257
+ // since these identifiers are what make up the export names,
1258
+ // e.g. export const { foo } = { foo: bar }; should pick up
1259
+ // `foo` but not `bar`.
1260
+ currentPath.parentPath?.isVariableDeclarator() && currentPath.parentKey === "id"
1261
+ ) {
1262
+ exportedVariableDeclarators.add(currentPath.parentPath.node);
1263
+ break;
1264
+ }
1265
+ currentPath = currentPath.parentPath;
1266
+ }
1267
+ }
1268
+ }
1269
+ let dependencies = {
1270
+ topLevelStatements,
1271
+ topLevelNonModuleStatements,
1272
+ importedIdentifierNames,
1273
+ exportedVariableDeclarators
1274
+ };
1275
+ exportDependencies.set(exportName, dependencies);
1276
+ }
1277
+ traverse(ast, {
1278
+ ExportDeclaration(exportPath) {
1279
+ let { node } = exportPath;
1280
+ if (t.isExportAllDeclaration(node)) {
1281
+ return;
1282
+ }
1283
+ if (t.isExportDefaultDeclaration(node)) {
1284
+ handleExport("default", exportPath);
1285
+ return;
1286
+ }
1287
+ let { declaration } = node;
1288
+ if (t.isVariableDeclaration(declaration)) {
1289
+ let { declarations } = declaration;
1290
+ for (let i = 0; i < declarations.length; i++) {
1291
+ let declarator = declarations[i];
1292
+ if (t.isIdentifier(declarator.id)) {
1293
+ let declaratorPath = exportPath.get(
1294
+ `declaration.declarations.${i}`
1295
+ );
1296
+ assertNodePathIsVariableDeclarator(declaratorPath);
1297
+ handleExport(declarator.id.name, exportPath, declaratorPath);
1298
+ continue;
1299
+ }
1300
+ if (t.isPattern(declarator.id)) {
1301
+ let exportedPatternPath = exportPath.get(
1302
+ `declaration.declarations.${i}.id`
1303
+ );
1304
+ assertNodePathIsPattern(exportedPatternPath);
1305
+ let identifiers = getIdentifiersForPatternPath(exportedPatternPath);
1306
+ for (let identifier of identifiers) {
1307
+ handleExport(identifier.node.name, exportPath, identifier);
1308
+ }
1309
+ }
1310
+ }
1311
+ return;
1312
+ }
1313
+ if (t.isFunctionDeclaration(declaration) || t.isClassDeclaration(declaration)) {
1314
+ invariant(
1315
+ declaration.id,
1316
+ "Expected exported function or class declaration to have a name when not the default export"
1317
+ );
1318
+ handleExport(declaration.id.name, exportPath);
1319
+ return;
1320
+ }
1321
+ if (t.isExportNamedDeclaration(node)) {
1322
+ for (let specifier of node.specifiers) {
1323
+ if (t.isIdentifier(specifier.exported)) {
1324
+ let name = specifier.exported.name;
1325
+ let specifierPath = exportPath.get("specifiers").find((path7) => path7.node === specifier);
1326
+ invariant(
1327
+ specifierPath,
1328
+ `Expected to find specifier path for ${name}`
1329
+ );
1330
+ handleExport(name, exportPath, specifierPath);
1331
+ }
1332
+ }
1333
+ return;
1334
+ }
1335
+ throw new Error(`Unknown export node type: ${node.type}`);
1336
+ }
1337
+ });
1338
+ return exportDependencies;
1339
+ }
1340
+ );
1341
+ }
1342
+ function getDependentIdentifiersForPath(path7, state) {
1343
+ let { visited, identifiers } = state ?? {
1344
+ visited: /* @__PURE__ */ new Set(),
1345
+ identifiers: /* @__PURE__ */ new Set()
1346
+ };
1347
+ if (visited.has(path7)) {
1348
+ return identifiers;
1349
+ }
1350
+ visited.add(path7);
1351
+ path7.traverse({
1352
+ Identifier(path8) {
1353
+ if (identifiers.has(path8)) {
1354
+ return;
1355
+ }
1356
+ identifiers.add(path8);
1357
+ let binding = path8.scope.getBinding(path8.node.name);
1358
+ if (!binding) {
1359
+ return;
1360
+ }
1361
+ getDependentIdentifiersForPath(binding.path, { visited, identifiers });
1362
+ for (let reference of binding.referencePaths) {
1363
+ if (reference.isExportNamedDeclaration()) {
1364
+ continue;
1365
+ }
1366
+ getDependentIdentifiersForPath(reference, {
1367
+ visited,
1368
+ identifiers
1369
+ });
1370
+ }
1371
+ for (let constantViolation of binding.constantViolations) {
1372
+ getDependentIdentifiersForPath(constantViolation, {
1373
+ visited,
1374
+ identifiers
1375
+ });
1376
+ }
1377
+ }
1378
+ });
1379
+ let topLevelStatement = getTopLevelStatementPathForPath(path7);
1380
+ let withinImportStatement = topLevelStatement.isImportDeclaration();
1381
+ let withinExportStatement = topLevelStatement.isExportDeclaration();
1382
+ if (!withinImportStatement && !withinExportStatement) {
1383
+ getDependentIdentifiersForPath(topLevelStatement, {
1384
+ visited,
1385
+ identifiers
1386
+ });
1387
+ }
1388
+ if (withinExportStatement && path7.isIdentifier() && (t.isPattern(path7.parentPath.node) || // [foo]
1389
+ t.isPattern(path7.parentPath.parentPath?.node))) {
1390
+ let variableDeclarator = path7.findParent((p) => p.isVariableDeclarator());
1391
+ assertNodePath(variableDeclarator);
1392
+ getDependentIdentifiersForPath(variableDeclarator, {
1393
+ visited,
1394
+ identifiers
1395
+ });
1396
+ }
1397
+ return identifiers;
1398
+ }
1399
+ function getTopLevelStatementPathForPath(path7) {
1400
+ let ancestry = path7.getAncestry();
1401
+ let topLevelStatement = ancestry[ancestry.length - 2];
1402
+ assertNodePathIsStatement(topLevelStatement);
1403
+ return topLevelStatement;
1404
+ }
1405
+ function getTopLevelStatementsForPaths(paths) {
1406
+ let topLevelStatements = /* @__PURE__ */ new Set();
1407
+ for (let path7 of paths) {
1408
+ let topLevelStatement = getTopLevelStatementPathForPath(path7);
1409
+ topLevelStatements.add(topLevelStatement.node);
1410
+ }
1411
+ return topLevelStatements;
1412
+ }
1413
+ function getIdentifiersForPatternPath(patternPath, identifiers = /* @__PURE__ */ new Set()) {
1414
+ function walk(currentPath) {
1415
+ if (currentPath.isIdentifier()) {
1416
+ identifiers.add(currentPath);
1417
+ return;
1418
+ }
1419
+ if (currentPath.isObjectPattern()) {
1420
+ let { properties } = currentPath.node;
1421
+ for (let i = 0; i < properties.length; i++) {
1422
+ const property = properties[i];
1423
+ if (t.isObjectProperty(property)) {
1424
+ let valuePath = currentPath.get(`properties.${i}.value`);
1425
+ assertNodePath(valuePath);
1426
+ walk(valuePath);
1427
+ } else if (t.isRestElement(property)) {
1428
+ let argumentPath = currentPath.get(`properties.${i}.argument`);
1429
+ assertNodePath(argumentPath);
1430
+ walk(argumentPath);
1431
+ }
1432
+ }
1433
+ } else if (currentPath.isArrayPattern()) {
1434
+ let { elements } = currentPath.node;
1435
+ for (let i = 0; i < elements.length; i++) {
1436
+ const element = elements[i];
1437
+ if (element) {
1438
+ let elementPath = currentPath.get(`elements.${i}`);
1439
+ assertNodePath(elementPath);
1440
+ walk(elementPath);
1441
+ }
1442
+ }
1443
+ } else if (currentPath.isRestElement()) {
1444
+ let argumentPath = currentPath.get("argument");
1445
+ assertNodePath(argumentPath);
1446
+ walk(argumentPath);
1447
+ }
1448
+ }
1449
+ walk(patternPath);
1450
+ return identifiers;
1451
+ }
1452
+ var getExportedName = (exported) => {
1453
+ return t.isIdentifier(exported) ? exported.name : exported.value;
1454
+ };
1455
+ function setsIntersect(set1, set2) {
1456
+ let smallerSet = set1;
1457
+ let largerSet = set2;
1458
+ if (set1.size > set2.size) {
1459
+ smallerSet = set2;
1460
+ largerSet = set1;
1461
+ }
1462
+ for (let element of smallerSet) {
1463
+ if (largerSet.has(element)) {
1464
+ return true;
1465
+ }
1466
+ }
1467
+ return false;
1468
+ }
1469
+ function hasChunkableExport(code, exportName, cache, cacheKey) {
1470
+ return getOrSetFromCache(
1471
+ cache,
1472
+ `${cacheKey}::hasChunkableExport::${exportName}`,
1473
+ code,
1474
+ () => {
1475
+ let exportDependencies = getExportDependencies(code, cache, cacheKey);
1476
+ let dependencies = exportDependencies.get(exportName);
1477
+ if (!dependencies) {
1478
+ return false;
1479
+ }
1480
+ for (let [currentExportName, currentDependencies] of exportDependencies) {
1481
+ if (currentExportName === exportName) {
1482
+ continue;
1483
+ }
1484
+ if (setsIntersect(
1485
+ currentDependencies.topLevelNonModuleStatements,
1486
+ dependencies.topLevelNonModuleStatements
1487
+ )) {
1488
+ return false;
1489
+ }
1490
+ }
1491
+ if (dependencies.exportedVariableDeclarators.size > 1) {
1492
+ return false;
1493
+ }
1494
+ if (dependencies.exportedVariableDeclarators.size > 0) {
1495
+ for (let [
1496
+ currentExportName,
1497
+ currentDependencies
1498
+ ] of exportDependencies) {
1499
+ if (currentExportName === exportName) {
1500
+ continue;
1501
+ }
1502
+ if (setsIntersect(
1503
+ currentDependencies.exportedVariableDeclarators,
1504
+ dependencies.exportedVariableDeclarators
1505
+ )) {
1506
+ return false;
1507
+ }
1508
+ }
1509
+ }
1510
+ return true;
1511
+ }
1512
+ );
1513
+ }
1514
+ function getChunkedExport(code, exportName, generateOptions = {}, cache, cacheKey) {
1515
+ return getOrSetFromCache(
1516
+ cache,
1517
+ `${cacheKey}::getChunkedExport::${exportName}::${JSON.stringify(
1518
+ generateOptions
1519
+ )}`,
1520
+ code,
1521
+ () => {
1522
+ if (!hasChunkableExport(code, exportName, cache, cacheKey)) {
1523
+ return void 0;
1524
+ }
1525
+ let exportDependencies = getExportDependencies(code, cache, cacheKey);
1526
+ let dependencies = exportDependencies.get(exportName);
1527
+ invariant(dependencies, "Expected export to have dependencies");
1528
+ let topLevelStatementsArray = Array.from(dependencies.topLevelStatements);
1529
+ let exportedVariableDeclaratorsArray = Array.from(
1530
+ dependencies.exportedVariableDeclarators
1531
+ );
1532
+ let ast = codeToAst(code, cache, cacheKey);
1533
+ ast.program.body = ast.program.body.filter(
1534
+ (node) => topLevelStatementsArray.some(
1535
+ (statement) => t.isNodesEquivalent(node, statement)
1536
+ )
1537
+ ).map((node) => {
1538
+ if (!t.isImportDeclaration(node)) {
1539
+ return node;
1540
+ }
1541
+ if (dependencies.importedIdentifierNames.size === 0) {
1542
+ return null;
1543
+ }
1544
+ node.specifiers = node.specifiers.filter(
1545
+ (specifier) => dependencies.importedIdentifierNames.has(specifier.local.name)
1546
+ );
1547
+ invariant(
1548
+ node.specifiers.length > 0,
1549
+ "Expected import statement to have used specifiers"
1550
+ );
1551
+ return node;
1552
+ }).map((node) => {
1553
+ if (!t.isExportDeclaration(node)) {
1554
+ return node;
1555
+ }
1556
+ if (t.isExportAllDeclaration(node)) {
1557
+ return null;
1558
+ }
1559
+ if (t.isExportDefaultDeclaration(node)) {
1560
+ return exportName === "default" ? node : null;
1561
+ }
1562
+ let { declaration } = node;
1563
+ if (t.isVariableDeclaration(declaration)) {
1564
+ declaration.declarations = declaration.declarations.filter(
1565
+ (node2) => exportedVariableDeclaratorsArray.some(
1566
+ (declarator) => t.isNodesEquivalent(node2, declarator)
1567
+ )
1568
+ );
1569
+ if (declaration.declarations.length === 0) {
1570
+ return null;
1571
+ }
1572
+ return node;
1573
+ }
1574
+ if (t.isFunctionDeclaration(node.declaration) || t.isClassDeclaration(node.declaration)) {
1575
+ return node.declaration.id?.name === exportName ? node : null;
1576
+ }
1577
+ if (t.isExportNamedDeclaration(node)) {
1578
+ if (node.specifiers.length === 0) {
1579
+ return null;
1580
+ }
1581
+ node.specifiers = node.specifiers.filter(
1582
+ (specifier) => getExportedName(specifier.exported) === exportName
1583
+ );
1584
+ if (node.specifiers.length === 0) {
1585
+ return null;
1586
+ }
1587
+ return node;
1588
+ }
1589
+ throw new Error(`Unknown export node type: ${node.type}`);
1590
+ }).filter((node) => node !== null);
1591
+ return generate2(ast, generateOptions);
1592
+ }
1593
+ );
1594
+ }
1595
+ function omitChunkedExports(code, exportNames, generateOptions = {}, cache, cacheKey) {
1596
+ return getOrSetFromCache(
1597
+ cache,
1598
+ `${cacheKey}::omitChunkedExports::${exportNames.join(
1599
+ ","
1600
+ )}::${JSON.stringify(generateOptions)}`,
1601
+ code,
1602
+ () => {
1603
+ const isChunkable = (exportName) => hasChunkableExport(code, exportName, cache, cacheKey);
1604
+ const isOmitted = (exportName) => exportNames.includes(exportName) && isChunkable(exportName);
1605
+ const isRetained = (exportName) => !isOmitted(exportName);
1606
+ let exportDependencies = getExportDependencies(code, cache, cacheKey);
1607
+ let allExportNames = Array.from(exportDependencies.keys());
1608
+ let omittedExportNames = allExportNames.filter(isOmitted);
1609
+ let retainedExportNames = allExportNames.filter(isRetained);
1610
+ let omittedStatements = /* @__PURE__ */ new Set();
1611
+ let omittedExportedVariableDeclarators = /* @__PURE__ */ new Set();
1612
+ for (let omittedExportName of omittedExportNames) {
1613
+ let dependencies = exportDependencies.get(omittedExportName);
1614
+ invariant(
1615
+ dependencies,
1616
+ `Expected dependencies for ${omittedExportName}`
1617
+ );
1618
+ for (let statement of dependencies.topLevelNonModuleStatements) {
1619
+ omittedStatements.add(statement);
1620
+ }
1621
+ for (let declarator of dependencies.exportedVariableDeclarators) {
1622
+ omittedExportedVariableDeclarators.add(declarator);
1623
+ }
1624
+ }
1625
+ let ast = codeToAst(code, cache, cacheKey);
1626
+ let omittedStatementsArray = Array.from(omittedStatements);
1627
+ let omittedExportedVariableDeclaratorsArray = Array.from(
1628
+ omittedExportedVariableDeclarators
1629
+ );
1630
+ ast.program.body = ast.program.body.filter(
1631
+ (node) => omittedStatementsArray.every(
1632
+ (statement) => !t.isNodesEquivalent(node, statement)
1633
+ )
1634
+ ).map((node) => {
1635
+ if (!t.isImportDeclaration(node)) {
1636
+ return node;
1637
+ }
1638
+ if (node.specifiers.length === 0) {
1639
+ return node;
1640
+ }
1641
+ node.specifiers = node.specifiers.filter((specifier) => {
1642
+ let importedName = specifier.local.name;
1643
+ for (let retainedExportName of retainedExportNames) {
1644
+ let dependencies = exportDependencies.get(retainedExportName);
1645
+ if (dependencies?.importedIdentifierNames?.has(importedName)) {
1646
+ return true;
1647
+ }
1648
+ }
1649
+ for (let omittedExportName of omittedExportNames) {
1650
+ let dependencies = exportDependencies.get(omittedExportName);
1651
+ if (dependencies?.importedIdentifierNames?.has(importedName)) {
1652
+ return false;
1653
+ }
1654
+ }
1655
+ return true;
1656
+ });
1657
+ if (node.specifiers.length === 0) {
1658
+ return null;
1659
+ }
1660
+ return node;
1661
+ }).map((node) => {
1662
+ if (!t.isExportDeclaration(node)) {
1663
+ return node;
1664
+ }
1665
+ if (t.isExportAllDeclaration(node)) {
1666
+ return node;
1667
+ }
1668
+ if (t.isExportDefaultDeclaration(node)) {
1669
+ return isOmitted("default") ? null : node;
1670
+ }
1671
+ if (t.isVariableDeclaration(node.declaration)) {
1672
+ node.declaration.declarations = node.declaration.declarations.filter(
1673
+ (node2) => omittedExportedVariableDeclaratorsArray.every(
1674
+ (declarator) => !t.isNodesEquivalent(node2, declarator)
1675
+ )
1676
+ );
1677
+ if (node.declaration.declarations.length === 0) {
1678
+ return null;
1679
+ }
1680
+ return node;
1681
+ }
1682
+ if (t.isFunctionDeclaration(node.declaration) || t.isClassDeclaration(node.declaration)) {
1683
+ invariant(
1684
+ node.declaration.id,
1685
+ "Expected exported function or class declaration to have a name when not the default export"
1686
+ );
1687
+ return isOmitted(node.declaration.id.name) ? null : node;
1688
+ }
1689
+ if (t.isExportNamedDeclaration(node)) {
1690
+ if (node.specifiers.length === 0) {
1691
+ return node;
1692
+ }
1693
+ node.specifiers = node.specifiers.filter((specifier) => {
1694
+ const exportedName = getExportedName(specifier.exported);
1695
+ return !isOmitted(exportedName);
1696
+ });
1697
+ if (node.specifiers.length === 0) {
1698
+ return null;
1699
+ }
1700
+ return node;
1701
+ }
1702
+ throw new Error(`Unknown node type: ${node.type}`);
1703
+ }).filter((node) => node !== null);
1704
+ if (ast.program.body.length === 0) {
1705
+ return void 0;
1706
+ }
1707
+ return generate2(ast, generateOptions);
1708
+ }
1709
+ );
1710
+ }
1711
+ function detectRouteChunks(code, cache, cacheKey) {
1712
+ const hasRouteChunkByExportName = Object.fromEntries(
1713
+ routeChunkExportNames.map((exportName) => [
1714
+ exportName,
1715
+ hasChunkableExport(code, exportName, cache, cacheKey)
1716
+ ])
1717
+ );
1718
+ const chunkedExports = Object.entries(hasRouteChunkByExportName).filter(([, isChunked]) => isChunked).map(([exportName]) => exportName);
1719
+ const hasRouteChunks = chunkedExports.length > 0;
1720
+ return {
1721
+ hasRouteChunks,
1722
+ hasRouteChunkByExportName,
1723
+ chunkedExports
1724
+ };
1725
+ }
1726
+ var routeChunkExportNames = [
1727
+ "clientAction",
1728
+ "clientLoader",
1729
+ "HydrateFallback"
1730
+ ];
1731
+ var mainChunkName = "main";
1732
+ var routeChunkNames = ["main", ...routeChunkExportNames];
1733
+ function getRouteChunkCode(code, chunkName, cache, cacheKey) {
1734
+ if (chunkName === mainChunkName) {
1735
+ return omitChunkedExports(code, routeChunkExportNames, {}, cache, cacheKey);
1736
+ }
1737
+ return getChunkedExport(code, chunkName, {}, cache, cacheKey);
1738
+ }
1739
+ var routeChunkQueryStringPrefix = "?route-chunk=";
1740
+ var routeChunkQueryStrings = {
1741
+ main: `${routeChunkQueryStringPrefix}main`,
1742
+ clientAction: `${routeChunkQueryStringPrefix}clientAction`,
1743
+ clientLoader: `${routeChunkQueryStringPrefix}clientLoader`,
1744
+ HydrateFallback: `${routeChunkQueryStringPrefix}HydrateFallback`
1745
+ };
1746
+ function getRouteChunkModuleId(filePath, chunkName) {
1747
+ return `${filePath}${routeChunkQueryStrings[chunkName]}`;
1748
+ }
1749
+ function isRouteChunkModuleId(id) {
1750
+ return Object.values(routeChunkQueryStrings).some(
1751
+ (queryString) => id.endsWith(queryString)
1752
+ );
1753
+ }
1754
+ function isRouteChunkName(name) {
1755
+ return name === mainChunkName || routeChunkExportNames.includes(name);
1756
+ }
1757
+ function getRouteChunkNameFromModuleId(id) {
1758
+ if (!isRouteChunkModuleId(id)) {
1759
+ return null;
1760
+ }
1761
+ let chunkName = id.split(routeChunkQueryStringPrefix)[1].split("&")[0];
1762
+ if (!isRouteChunkName(chunkName)) {
1763
+ return null;
1764
+ }
1765
+ return chunkName;
1766
+ }
1767
+
1164
1768
  // vite/with-props.ts
1165
1769
  var import_dedent2 = __toESM(require("dedent"));
1166
1770
  var vmod = create("with-props");
@@ -1286,11 +1890,10 @@ function toFunctionExpression(decl) {
1286
1890
  }
1287
1891
 
1288
1892
  // vite/plugin.ts
1289
- var SERVER_ONLY_ROUTE_EXPORTS = ["loader", "action", "middleware", "headers"];
1893
+ var SERVER_ONLY_ROUTE_EXPORTS = ["loader", "action", "headers"];
1290
1894
  var CLIENT_ROUTE_EXPORTS = [
1291
1895
  "clientAction",
1292
1896
  "clientLoader",
1293
- "clientMiddleware",
1294
1897
  "default",
1295
1898
  "ErrorBoundary",
1296
1899
  "handle",
@@ -1301,8 +1904,20 @@ var CLIENT_ROUTE_EXPORTS = [
1301
1904
  "shouldRevalidate"
1302
1905
  ];
1303
1906
  var BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
1907
+ var isRouteEntryModuleId = (id) => {
1908
+ return id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING);
1909
+ };
1910
+ var isRouteVirtualModule = (id) => {
1911
+ return isRouteEntryModuleId(id) || isRouteChunkModuleId(id);
1912
+ };
1304
1913
  var virtualHmrRuntime = create("hmr-runtime");
1305
1914
  var virtualInjectHmrRuntime = create("inject-hmr-runtime");
1915
+ var normalizeRelativeFilePath = (file, reactRouterConfig) => {
1916
+ let vite2 = getVite();
1917
+ let fullPath = path6.resolve(reactRouterConfig.appDirectory, file);
1918
+ let relativePath = path6.relative(reactRouterConfig.appDirectory, fullPath);
1919
+ return vite2.normalizePath(relativePath).split("?")[0];
1920
+ };
1306
1921
  var resolveRelativeRouteFilePath = (route, reactRouterConfig) => {
1307
1922
  let vite2 = getVite();
1308
1923
  let file = route.file;
@@ -1331,23 +1946,35 @@ var resolveChunk = (ctx, viteManifest, absoluteFilePath) => {
1331
1946
  let rootRelativeFilePath = vite2.normalizePath(
1332
1947
  path6.relative(ctx.rootDirectory, absoluteFilePath)
1333
1948
  );
1334
- let entryChunk = viteManifest[rootRelativeFilePath + BUILD_CLIENT_ROUTE_QUERY_STRING] ?? viteManifest[rootRelativeFilePath];
1949
+ let entryChunk = viteManifest[rootRelativeFilePath];
1335
1950
  if (!entryChunk) {
1336
- let knownManifestKeys = Object.keys(viteManifest).map((key) => '"' + key + '"').join(", ");
1337
- throw new Error(
1338
- `No manifest entry found for "${rootRelativeFilePath}". Known manifest keys: ${knownManifestKeys}`
1339
- );
1951
+ return void 0;
1340
1952
  }
1341
1953
  return entryChunk;
1342
1954
  };
1955
+ var getPublicModulePathForEntry = (ctx, viteManifest, entryFilePath) => {
1956
+ let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
1957
+ return entryChunk ? `${ctx.publicPath}${entryChunk.file}` : void 0;
1958
+ };
1343
1959
  var getReactRouterManifestBuildAssets = (ctx, viteManifest, entryFilePath, prependedAssetFilePaths = []) => {
1344
1960
  let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
1345
- let prependedAssetChunks = prependedAssetFilePaths.map(
1346
- (filePath) => resolveChunk(ctx, viteManifest, filePath)
1347
- );
1961
+ invariant(entryChunk, "Chunk not found");
1962
+ let prependedAssetChunks = prependedAssetFilePaths.map((filePath) => {
1963
+ let chunk = resolveChunk(ctx, viteManifest, filePath);
1964
+ invariant(chunk, "Chunk not found");
1965
+ return chunk;
1966
+ });
1967
+ let routeModuleChunks = routeChunkNames.map(
1968
+ (routeChunkName) => resolveChunk(
1969
+ ctx,
1970
+ viteManifest,
1971
+ getRouteChunkModuleId(entryFilePath.split("?")[0], routeChunkName)
1972
+ )
1973
+ ).filter(isNonNullable);
1348
1974
  let chunks = resolveDependantChunks(viteManifest, [
1349
1975
  ...prependedAssetChunks,
1350
- entryChunk
1976
+ entryChunk,
1977
+ ...routeModuleChunks
1351
1978
  ]);
1352
1979
  return {
1353
1980
  module: `${ctx.publicPath}${entryChunk.file}`,
@@ -1384,6 +2011,10 @@ var writeFileSafe = async (file, contents) => {
1384
2011
  await fse.ensureDir(path6.dirname(file));
1385
2012
  await fse.writeFile(file, contents);
1386
2013
  };
2014
+ var getExportNames = (code) => {
2015
+ let [, exportSpecifiers] = (0, import_es_module_lexer.parse)(code);
2016
+ return exportSpecifiers.map(({ n: name }) => name);
2017
+ };
1387
2018
  var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
1388
2019
  let entries = await Promise.all(
1389
2020
  Object.entries(ctx.reactRouterConfig.routes).map(async ([key, route]) => {
@@ -1397,7 +2028,7 @@ var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
1397
2028
  );
1398
2029
  return Object.fromEntries(entries);
1399
2030
  };
1400
- var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
2031
+ var compileRouteFile = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
1401
2032
  if (!viteChildCompiler) {
1402
2033
  throw new Error("Vite child compiler not found");
1403
2034
  }
@@ -1417,9 +2048,19 @@ var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteF
1417
2048
  moduleGraph.ensureEntryFromUrl(url2, ssr)
1418
2049
  ]);
1419
2050
  let transformed = await pluginContainer.transform(code, id, { ssr });
1420
- let [, exports2] = (0, import_es_module_lexer.parse)(transformed.code);
1421
- let exportNames = exports2.map((e) => e.n);
1422
- return exportNames;
2051
+ return transformed.code;
2052
+ };
2053
+ var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
2054
+ if (!viteChildCompiler) {
2055
+ throw new Error("Vite child compiler not found");
2056
+ }
2057
+ let code = await compileRouteFile(
2058
+ viteChildCompiler,
2059
+ ctx,
2060
+ routeFile,
2061
+ readRouteFile
2062
+ );
2063
+ return getExportNames(code);
1423
2064
  };
1424
2065
  var getServerBundleBuildConfig = (viteUserConfig) => {
1425
2066
  if (!("__reactRouterServerBundleBuildConfig" in viteUserConfig) || !viteUserConfig.__reactRouterServerBundleBuildConfig) {
@@ -1450,6 +2091,7 @@ var reactRouterVitePlugin = () => {
1450
2091
  let viteConfig;
1451
2092
  let cssModulesManifest = {};
1452
2093
  let viteChildCompiler = null;
2094
+ let cache = /* @__PURE__ */ new Map();
1453
2095
  let reactRouterConfigLoader;
1454
2096
  let typegenWatcherPromise;
1455
2097
  let logger;
@@ -1589,13 +2231,31 @@ var reactRouterVitePlugin = () => {
1589
2231
  viteChildCompiler,
1590
2232
  ctx
1591
2233
  );
2234
+ let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
1592
2235
  for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
1593
- let routeFilePath = path6.join(
1594
- ctx.reactRouterConfig.appDirectory,
1595
- route.file
1596
- );
2236
+ let routeFile = path6.join(ctx.reactRouterConfig.appDirectory, route.file);
1597
2237
  let sourceExports = routeManifestExports[key];
1598
2238
  let isRootRoute = route.parentId === void 0;
2239
+ let hasClientAction = sourceExports.includes("clientAction");
2240
+ let hasClientLoader = sourceExports.includes("clientLoader");
2241
+ let hasHydrateFallback = sourceExports.includes("HydrateFallback");
2242
+ let { hasRouteChunkByExportName } = await detectRouteChunksIfEnabled(
2243
+ cache,
2244
+ ctx,
2245
+ routeFile,
2246
+ { routeFile, viteChildCompiler }
2247
+ );
2248
+ if (enforceSplitRouteModules) {
2249
+ validateRouteChunks({
2250
+ ctx,
2251
+ id: route.file,
2252
+ valid: {
2253
+ clientAction: !hasClientAction || hasRouteChunkByExportName.clientAction,
2254
+ clientLoader: !hasClientLoader || hasRouteChunkByExportName.clientLoader,
2255
+ HydrateFallback: !hasHydrateFallback || hasRouteChunkByExportName.HydrateFallback
2256
+ }
2257
+ });
2258
+ }
1599
2259
  let routeManifestEntry = {
1600
2260
  id: route.id,
1601
2261
  parentId: route.parentId,
@@ -1604,18 +2264,33 @@ var reactRouterVitePlugin = () => {
1604
2264
  caseSensitive: route.caseSensitive,
1605
2265
  hasAction: sourceExports.includes("action"),
1606
2266
  hasLoader: sourceExports.includes("loader"),
1607
- hasClientAction: sourceExports.includes("clientAction"),
1608
- hasClientLoader: sourceExports.includes("clientLoader"),
2267
+ hasClientAction,
2268
+ hasClientLoader,
1609
2269
  hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
1610
2270
  ...getReactRouterManifestBuildAssets(
1611
2271
  ctx,
1612
2272
  viteManifest,
1613
- routeFilePath,
2273
+ `${routeFile}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
1614
2274
  // If this is the root route, we also need to include assets from the
1615
2275
  // client entry file as this is a common way for consumers to import
1616
2276
  // global reset styles, etc.
1617
2277
  isRootRoute ? [ctx.entryClientFilePath] : []
1618
- )
2278
+ ),
2279
+ clientActionModule: hasRouteChunkByExportName.clientAction ? getPublicModulePathForEntry(
2280
+ ctx,
2281
+ viteManifest,
2282
+ getRouteChunkModuleId(routeFile, "clientAction")
2283
+ ) : void 0,
2284
+ clientLoaderModule: hasRouteChunkByExportName.clientLoader ? getPublicModulePathForEntry(
2285
+ ctx,
2286
+ viteManifest,
2287
+ getRouteChunkModuleId(routeFile, "clientLoader")
2288
+ ) : void 0,
2289
+ hydrateFallbackModule: hasRouteChunkByExportName.HydrateFallback ? getPublicModulePathForEntry(
2290
+ ctx,
2291
+ viteManifest,
2292
+ getRouteChunkModuleId(routeFile, "HydrateFallback")
2293
+ ) : void 0
1619
2294
  };
1620
2295
  browserRoutes[key] = routeManifestEntry;
1621
2296
  let serverBundleRoutes = ctx.serverBundleBuildConfig?.routes;
@@ -1656,25 +2331,52 @@ var reactRouterVitePlugin = () => {
1656
2331
  viteChildCompiler,
1657
2332
  ctx
1658
2333
  );
2334
+ let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
1659
2335
  for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
2336
+ let routeFile = route.file;
1660
2337
  let sourceExports = routeManifestExports[key];
2338
+ let hasClientAction = sourceExports.includes("clientAction");
2339
+ let hasClientLoader = sourceExports.includes("clientLoader");
2340
+ let hasHydrateFallback = sourceExports.includes("HydrateFallback");
2341
+ let routeModulePath = combineURLs(
2342
+ ctx.publicPath,
2343
+ `${resolveFileUrl(
2344
+ ctx,
2345
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
2346
+ )}`
2347
+ );
2348
+ if (enforceSplitRouteModules) {
2349
+ let { hasRouteChunkByExportName } = await detectRouteChunksIfEnabled(
2350
+ cache,
2351
+ ctx,
2352
+ routeFile,
2353
+ { routeFile, viteChildCompiler }
2354
+ );
2355
+ validateRouteChunks({
2356
+ ctx,
2357
+ id: route.file,
2358
+ valid: {
2359
+ clientAction: !hasClientAction || hasRouteChunkByExportName.clientAction,
2360
+ clientLoader: !hasClientLoader || hasRouteChunkByExportName.clientLoader,
2361
+ HydrateFallback: !hasHydrateFallback || hasRouteChunkByExportName.HydrateFallback
2362
+ }
2363
+ });
2364
+ }
1661
2365
  routes[key] = {
1662
2366
  id: route.id,
1663
2367
  parentId: route.parentId,
1664
2368
  path: route.path,
1665
2369
  index: route.index,
1666
2370
  caseSensitive: route.caseSensitive,
1667
- module: combineURLs(
1668
- ctx.publicPath,
1669
- resolveFileUrl(
1670
- ctx,
1671
- resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
1672
- )
1673
- ),
2371
+ module: routeModulePath,
2372
+ // Split route modules are a build-time optimization
2373
+ clientActionModule: void 0,
2374
+ clientLoaderModule: void 0,
2375
+ hydrateFallbackModule: void 0,
1674
2376
  hasAction: sourceExports.includes("action"),
1675
2377
  hasLoader: sourceExports.includes("loader"),
1676
- hasClientAction: sourceExports.includes("clientAction"),
1677
- hasClientLoader: sourceExports.includes("clientLoader"),
2378
+ hasClientAction,
2379
+ hasClientLoader,
1678
2380
  hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
1679
2381
  imports: []
1680
2382
  };
@@ -1827,12 +2529,28 @@ var reactRouterVitePlugin = () => {
1827
2529
  preserveEntrySignatures: "exports-only",
1828
2530
  input: [
1829
2531
  ctx.entryClientFilePath,
1830
- ...Object.values(ctx.reactRouterConfig.routes).map(
1831
- (route) => `${path6.resolve(
2532
+ ...Object.values(
2533
+ ctx.reactRouterConfig.routes
2534
+ ).flatMap((route) => {
2535
+ let routeFilePath = path6.resolve(
1832
2536
  ctx.reactRouterConfig.appDirectory,
1833
2537
  route.file
1834
- )}${BUILD_CLIENT_ROUTE_QUERY_STRING}`
1835
- )
2538
+ );
2539
+ let isRootRoute = route.file === ctx.reactRouterConfig.routes.root.file;
2540
+ let code = fse.readFileSync(
2541
+ routeFilePath,
2542
+ "utf-8"
2543
+ );
2544
+ return [
2545
+ `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
2546
+ ...ctx.reactRouterConfig.future.unstable_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
2547
+ (exportName) => code.includes(exportName) ? getRouteChunkModuleId(
2548
+ routeFilePath,
2549
+ exportName
2550
+ ) : null
2551
+ ) : []
2552
+ ].filter(isNonNullable);
2553
+ })
1836
2554
  ]
1837
2555
  }
1838
2556
  } : {
@@ -2102,10 +2820,59 @@ var reactRouterVitePlugin = () => {
2102
2820
  await typegenWatcher?.close();
2103
2821
  }
2104
2822
  },
2823
+ {
2824
+ name: "react-router:route-chunks-index",
2825
+ // This plugin provides the route module "index" since route modules can
2826
+ // be chunked and may be made up of multiple smaller modules. This plugin
2827
+ // primarily ensures code is never duplicated across a route module and
2828
+ // its chunks. If we didn't have this plugin, any app that explicitly
2829
+ // imports a route module would result in duplicate code since the app
2830
+ // would contain code for both the unprocessed route module as well as its
2831
+ // individual chunks. This is because, since they have different module
2832
+ // IDs, they are treated as completely separate modules even though they
2833
+ // all reference the same underlying file. This plugin addresses this by
2834
+ // ensuring that any explicit imports of a route module resolve to a
2835
+ // module that simply re-exports from its underlying chunks, if present.
2836
+ async transform(code, id, options) {
2837
+ if (viteCommand !== "build") return;
2838
+ if (options?.ssr) {
2839
+ return;
2840
+ }
2841
+ if (!isRoute(ctx.reactRouterConfig, id)) {
2842
+ return;
2843
+ }
2844
+ if (isRouteVirtualModule(id)) {
2845
+ return;
2846
+ }
2847
+ let { hasRouteChunks, chunkedExports } = await detectRouteChunksIfEnabled(cache, ctx, id, code);
2848
+ if (!hasRouteChunks) {
2849
+ return;
2850
+ }
2851
+ let sourceExports = await getRouteModuleExports(
2852
+ viteChildCompiler,
2853
+ ctx,
2854
+ id
2855
+ );
2856
+ let isMainChunkExport = (name) => !chunkedExports.includes(name);
2857
+ let mainChunkReexports = sourceExports.filter(isMainChunkExport).join(", ");
2858
+ let chunkBasePath = `./${path6.basename(id)}`;
2859
+ return [
2860
+ `export { ${mainChunkReexports} } from "${getRouteChunkModuleId(
2861
+ chunkBasePath,
2862
+ "main"
2863
+ )}";`,
2864
+ ...chunkedExports.map(
2865
+ (exportName) => `export { ${exportName} } from "${getRouteChunkModuleId(
2866
+ chunkBasePath,
2867
+ exportName
2868
+ )}";`
2869
+ )
2870
+ ].filter(Boolean).join("\n");
2871
+ }
2872
+ },
2105
2873
  {
2106
2874
  name: "react-router:build-client-route",
2107
- enforce: "pre",
2108
- async transform(_code, id, options) {
2875
+ async transform(code, id, options) {
2109
2876
  if (!id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING)) return;
2110
2877
  let routeModuleId = id.replace(BUILD_CLIENT_ROUTE_QUERY_STRING, "");
2111
2878
  let routeFileName = path6.basename(routeModuleId);
@@ -2114,12 +2881,59 @@ var reactRouterVitePlugin = () => {
2114
2881
  ctx,
2115
2882
  routeModuleId
2116
2883
  );
2117
- let reexports = sourceExports.filter(
2118
- (exportName) => options?.ssr && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS.includes(exportName)
2119
- ).join(", ");
2884
+ let { chunkedExports = [] } = options?.ssr ? {} : await detectRouteChunksIfEnabled(cache, ctx, id, code);
2885
+ let reexports = sourceExports.filter((exportName) => {
2886
+ let isRouteEntryExport = options?.ssr && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS.includes(exportName);
2887
+ let isChunkedExport = chunkedExports.includes(
2888
+ exportName
2889
+ );
2890
+ return isRouteEntryExport && !isChunkedExport;
2891
+ }).join(", ");
2120
2892
  return `export { ${reexports} } from "./${routeFileName}";`;
2121
2893
  }
2122
2894
  },
2895
+ {
2896
+ name: "react-router:split-route-modules",
2897
+ async transform(code, id, options) {
2898
+ if (options?.ssr) return;
2899
+ if (!isRouteChunkModuleId(id)) return;
2900
+ invariant(
2901
+ viteCommand === "build",
2902
+ "Route modules are only split in build mode"
2903
+ );
2904
+ let chunkName = getRouteChunkNameFromModuleId(id);
2905
+ if (!chunkName) {
2906
+ throw new Error(`Invalid route chunk name "${chunkName}" in "${id}"`);
2907
+ }
2908
+ let chunk = await getRouteChunkIfEnabled(
2909
+ cache,
2910
+ ctx,
2911
+ id,
2912
+ chunkName,
2913
+ code
2914
+ );
2915
+ let preventEmptyChunkSnippet = ({ reason }) => `Math.random()<0&&console.log(${JSON.stringify(reason)});`;
2916
+ if (chunk === null) {
2917
+ return preventEmptyChunkSnippet({
2918
+ reason: "Split round modules disabled"
2919
+ });
2920
+ }
2921
+ let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
2922
+ if (enforceSplitRouteModules && chunkName === "main" && chunk) {
2923
+ let exportNames = getExportNames(chunk.code);
2924
+ validateRouteChunks({
2925
+ ctx,
2926
+ id,
2927
+ valid: {
2928
+ clientAction: !exportNames.includes("clientAction"),
2929
+ clientLoader: !exportNames.includes("clientLoader"),
2930
+ HydrateFallback: !exportNames.includes("HydrateFallback")
2931
+ }
2932
+ });
2933
+ }
2934
+ return chunk ?? preventEmptyChunkSnippet({ reason: `No ${chunkName} chunk` });
2935
+ }
2936
+ },
2123
2937
  {
2124
2938
  name: "react-router:virtual-modules",
2125
2939
  enforce: "pre",
@@ -2174,8 +2988,7 @@ var reactRouterVitePlugin = () => {
2174
2988
  let importerShort = vite2.normalizePath(
2175
2989
  path6.relative(ctx.rootDirectory, importer)
2176
2990
  );
2177
- let isRoute = getRoute(ctx.reactRouterConfig, importer);
2178
- if (isRoute) {
2991
+ if (isRoute(ctx.reactRouterConfig, importer)) {
2179
2992
  let serverOnlyExports = SERVER_ONLY_ROUTE_EXPORTS.map(
2180
2993
  (xport) => `\`${xport}\``
2181
2994
  ).join(", ");
@@ -2214,10 +3027,10 @@ var reactRouterVitePlugin = () => {
2214
3027
  let clientFileRE = /\.client(\.[cm]?[jt]sx?)?$/;
2215
3028
  let clientDirRE = /\/\.client\//;
2216
3029
  if (clientFileRE.test(id) || clientDirRE.test(id)) {
2217
- let exports2 = (0, import_es_module_lexer.parse)(code)[1];
3030
+ let exports2 = getExportNames(code);
2218
3031
  return {
2219
3032
  code: exports2.map(
2220
- ({ n: name }) => name === "default" ? "export default undefined;" : `export const ${name} = undefined;`
3033
+ (name) => name === "default" ? "export default undefined;" : `export const ${name} = undefined;`
2221
3034
  ).join("\n"),
2222
3035
  map: null
2223
3036
  };
@@ -2228,17 +3041,25 @@ var reactRouterVitePlugin = () => {
2228
3041
  {
2229
3042
  name: "react-router:route-exports",
2230
3043
  async transform(code, id, options) {
3044
+ if (isRouteChunkModuleId(id)) {
3045
+ id = id.split("?")[0];
3046
+ }
2231
3047
  let route = getRoute(ctx.reactRouterConfig, id);
2232
3048
  if (!route) return;
2233
3049
  if (!options?.ssr && !ctx.reactRouterConfig.ssr) {
2234
- let serverOnlyExports = (0, import_es_module_lexer.parse)(code)[1].map((exp) => exp.n).filter((exp) => SERVER_ONLY_ROUTE_EXPORTS.includes(exp));
3050
+ let exportNames = getExportNames(code);
3051
+ let serverOnlyExports = exportNames.filter(
3052
+ (exp) => SERVER_ONLY_ROUTE_EXPORTS.includes(exp)
3053
+ );
2235
3054
  if (serverOnlyExports.length > 0) {
2236
3055
  let str = serverOnlyExports.map((e) => `\`${e}\``).join(", ");
2237
3056
  let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://remix.run/guides/spa-mode for more information.`;
2238
3057
  throw Error(message);
2239
3058
  }
2240
3059
  if (route.id !== "root") {
2241
- let hasHydrateFallback = (0, import_es_module_lexer.parse)(code)[1].map((exp) => exp.n).some((exp) => exp === "HydrateFallback");
3060
+ let hasHydrateFallback = exportNames.some(
3061
+ (exp) => exp === "HydrateFallback"
3062
+ );
2242
3063
  if (hasHydrateFallback) {
2243
3064
  let message = `SPA Mode: Invalid \`HydrateFallback\` export found in \`${route.file}\`. \`HydrateFallback\` is only permitted on the root route in SPA Mode. See https://remix.run/guides/spa-mode for more information.`;
2244
3065
  throw Error(message);
@@ -2316,6 +3137,9 @@ var reactRouterVitePlugin = () => {
2316
3137
  let isJSX = filepath.endsWith("x");
2317
3138
  let useFastRefresh = !ssr && (isJSX || code.includes(devRuntime));
2318
3139
  if (!useFastRefresh) return;
3140
+ if (isRouteVirtualModule(id)) {
3141
+ return { code: addRefreshWrapper(ctx.reactRouterConfig, code, id) };
3142
+ }
2319
3143
  let result = await babel.transformAsync(code, {
2320
3144
  babelrc: false,
2321
3145
  configFile: false,
@@ -2346,6 +3170,7 @@ var reactRouterVitePlugin = () => {
2346
3170
  let serverManifest = (await server.ssrLoadModule(virtual.serverManifest.id)).default;
2347
3171
  let oldRouteMetadata = serverManifest.routes[route.id];
2348
3172
  let newRouteMetadata = await getRouteMetadata(
3173
+ cache,
2349
3174
  ctx,
2350
3175
  viteChildCompiler,
2351
3176
  route,
@@ -2355,9 +3180,12 @@ var reactRouterVitePlugin = () => {
2355
3180
  if (!oldRouteMetadata || [
2356
3181
  "hasLoader",
2357
3182
  "hasClientLoader",
3183
+ "clientLoaderModule",
2358
3184
  "hasAction",
2359
3185
  "hasClientAction",
2360
- "hasErrorBoundary"
3186
+ "clientActionModule",
3187
+ "hasErrorBoundary",
3188
+ "hydrateFallbackModule"
2361
3189
  ].some((key) => oldRouteMetadata[key] !== newRouteMetadata[key])) {
2362
3190
  invalidateVirtualModules(server);
2363
3191
  }
@@ -2423,7 +3251,6 @@ function addRefreshWrapper(reactRouterConfig, code, id) {
2423
3251
  let acceptExports = route ? [
2424
3252
  "clientAction",
2425
3253
  "clientLoader",
2426
- "clientMiddleware",
2427
3254
  "handle",
2428
3255
  "meta",
2429
3256
  "links",
@@ -2476,13 +3303,30 @@ function getRoute(pluginConfig, file) {
2476
3303
  );
2477
3304
  return route;
2478
3305
  }
2479
- async function getRouteMetadata(ctx, viteChildCompiler, route, readRouteFile) {
3306
+ function isRoute(pluginConfig, file) {
3307
+ return Boolean(getRoute(pluginConfig, file));
3308
+ }
3309
+ async function getRouteMetadata(cache, ctx, viteChildCompiler, route, readRouteFile) {
3310
+ let routeFile = route.file;
2480
3311
  let sourceExports = await getRouteModuleExports(
2481
3312
  viteChildCompiler,
2482
3313
  ctx,
2483
3314
  route.file,
2484
3315
  readRouteFile
2485
3316
  );
3317
+ let { hasRouteChunkByExportName } = await detectRouteChunksIfEnabled(
3318
+ cache,
3319
+ ctx,
3320
+ routeFile,
3321
+ { routeFile, readRouteFile, viteChildCompiler }
3322
+ );
3323
+ let moduleUrl = combineURLs(
3324
+ ctx.publicPath,
3325
+ `${resolveFileUrl(
3326
+ ctx,
3327
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
3328
+ )}`
3329
+ );
2486
3330
  let info = {
2487
3331
  id: route.id,
2488
3332
  parentId: route.parentId,
@@ -2496,14 +3340,11 @@ async function getRouteMetadata(ctx, viteChildCompiler, route, readRouteFile) {
2496
3340
  resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
2497
3341
  )
2498
3342
  ),
2499
- module: combineURLs(
2500
- ctx.publicPath,
2501
- `${resolveFileUrl(
2502
- ctx,
2503
- resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
2504
- )}?import`
2505
- ),
3343
+ module: `${moduleUrl}?import`,
2506
3344
  // Ensure the Vite dev server responds with a JS module
3345
+ clientActionModule: hasRouteChunkByExportName.clientAction ? `${getRouteChunkModuleId(moduleUrl, "clientAction")}` : void 0,
3346
+ clientLoaderModule: hasRouteChunkByExportName.clientLoader ? `${getRouteChunkModuleId(moduleUrl, "clientLoader")}` : void 0,
3347
+ hydrateFallbackModule: hasRouteChunkByExportName.HydrateFallback ? `${getRouteChunkModuleId(moduleUrl, "HydrateFallback")}` : void 0,
2507
3348
  hasAction: sourceExports.includes("action"),
2508
3349
  hasClientAction: sourceExports.includes("clientAction"),
2509
3350
  hasLoader: sourceExports.includes("loader"),
@@ -2738,8 +3579,6 @@ function createPrerenderRoutes(manifest, parentId = "", routesByParentId = group
2738
3579
  loader: route.module.loader ? () => null : void 0,
2739
3580
  action: void 0,
2740
3581
  handle: route.module.handle
2741
- // middleware is not necessary here since we just need to know which
2742
- // routes have loaders so we know what paths to prerender
2743
3582
  };
2744
3583
  return route.index ? {
2745
3584
  index: true,
@@ -2751,6 +3590,73 @@ function createPrerenderRoutes(manifest, parentId = "", routesByParentId = group
2751
3590
  };
2752
3591
  });
2753
3592
  }
3593
+ var resolveRouteFileCode = async (ctx, input) => {
3594
+ if (typeof input === "string") return input;
3595
+ invariant(input.viteChildCompiler);
3596
+ return await compileRouteFile(
3597
+ input.viteChildCompiler,
3598
+ ctx,
3599
+ input.routeFile,
3600
+ input.readRouteFile
3601
+ );
3602
+ };
3603
+ async function detectRouteChunksIfEnabled(cache, ctx, id, input) {
3604
+ function noRouteChunks() {
3605
+ return {
3606
+ chunkedExports: [],
3607
+ hasRouteChunks: false,
3608
+ hasRouteChunkByExportName: {
3609
+ clientAction: false,
3610
+ clientLoader: false,
3611
+ HydrateFallback: false
3612
+ }
3613
+ };
3614
+ }
3615
+ if (!ctx.reactRouterConfig.future.unstable_splitRouteModules) {
3616
+ return noRouteChunks();
3617
+ }
3618
+ if (normalizeRelativeFilePath(id, ctx.reactRouterConfig) === ctx.reactRouterConfig.routes.root.file) {
3619
+ return noRouteChunks();
3620
+ }
3621
+ let code = await resolveRouteFileCode(ctx, input);
3622
+ if (!routeChunkExportNames.some((exportName) => code.includes(exportName))) {
3623
+ return noRouteChunks();
3624
+ }
3625
+ let cacheKey = normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read");
3626
+ return detectRouteChunks(code, cache, cacheKey);
3627
+ }
3628
+ async function getRouteChunkIfEnabled(cache, ctx, id, chunkName, input) {
3629
+ if (!ctx.reactRouterConfig.future.unstable_splitRouteModules) {
3630
+ return null;
3631
+ }
3632
+ let code = await resolveRouteFileCode(ctx, input);
3633
+ let cacheKey = normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read");
3634
+ return getRouteChunkCode(code, chunkName, cache, cacheKey);
3635
+ }
3636
+ function validateRouteChunks({
3637
+ ctx,
3638
+ id,
3639
+ valid
3640
+ }) {
3641
+ let invalidChunks = Object.entries(valid).filter(([_, isValid]) => !isValid).map(([chunkName]) => chunkName);
3642
+ if (invalidChunks.length === 0) {
3643
+ return;
3644
+ }
3645
+ let plural = invalidChunks.length > 1;
3646
+ throw new Error(
3647
+ [
3648
+ `Error splitting route module: ${normalizeRelativeFilePath(
3649
+ id,
3650
+ ctx.reactRouterConfig
3651
+ )}`,
3652
+ invalidChunks.map((name) => `- ${name}`).join("\n"),
3653
+ `${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.`
3654
+ ].join("\n\n")
3655
+ );
3656
+ }
3657
+ function isNonNullable(x) {
3658
+ return x != null;
3659
+ }
2754
3660
  // Annotate the CommonJS export names for ESM import in node:
2755
3661
  0 && (module.exports = {
2756
3662
  reactRouter