@react-router/dev 0.0.0-experimental-759a11a62 → 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/CHANGELOG.md +23 -0
- package/dist/cli/index.js +233 -244
- package/dist/config/defaults/entry.server.node.tsx +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js +1 -1
- package/dist/routes.js +1 -1
- package/dist/vite/cloudflare.js +1 -1
- package/dist/vite.js +1095 -190
- package/module-sync-enabled/false.cjs +1 -0
- package/module-sync-enabled/index.d.mts +2 -0
- package/module-sync-enabled/index.mjs +4 -0
- package/module-sync-enabled/true.mjs +2 -0
- package/package.json +14 -6
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v0.0.0-experimental-
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-df0f1dfda
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -57,8 +57,7 @@ var import_picocolors3 = __toESM(require("picocolors"));
|
|
|
57
57
|
|
|
58
58
|
// typegen/index.ts
|
|
59
59
|
var import_node_fs2 = __toESM(require("fs"));
|
|
60
|
-
var
|
|
61
|
-
var Path3 = __toESM(require("pathe"));
|
|
60
|
+
var Path4 = __toESM(require("pathe"));
|
|
62
61
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
63
62
|
|
|
64
63
|
// config/config.ts
|
|
@@ -444,7 +443,8 @@ async function resolveConfig({
|
|
|
444
443
|
);
|
|
445
444
|
}
|
|
446
445
|
let future = {
|
|
447
|
-
unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false
|
|
446
|
+
unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
|
|
447
|
+
unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false
|
|
448
448
|
};
|
|
449
449
|
let reactRouterConfig = deepFreeze({
|
|
450
450
|
appDirectory,
|
|
@@ -625,54 +625,125 @@ function findEntry(dir, basename2, options) {
|
|
|
625
625
|
|
|
626
626
|
// typegen/generate.ts
|
|
627
627
|
var import_dedent = __toESM(require("dedent"));
|
|
628
|
-
|
|
628
|
+
var Path3 = __toESM(require("pathe"));
|
|
629
|
+
var Pathe2 = __toESM(require("pathe/utils"));
|
|
630
|
+
|
|
631
|
+
// typegen/paths.ts
|
|
632
|
+
var Path2 = __toESM(require("pathe"));
|
|
633
|
+
var Pathe = __toESM(require("pathe/utils"));
|
|
634
|
+
function getTypesDir(ctx) {
|
|
635
|
+
return Path2.join(ctx.rootDirectory, ".react-router/types");
|
|
636
|
+
}
|
|
637
|
+
function getTypesPath(ctx, route) {
|
|
638
|
+
return Path2.join(
|
|
639
|
+
getTypesDir(ctx),
|
|
640
|
+
Path2.relative(ctx.rootDirectory, ctx.config.appDirectory),
|
|
641
|
+
Path2.dirname(route.file),
|
|
642
|
+
"+types/" + Pathe.filename(route.file) + ".ts"
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// typegen/generate.ts
|
|
647
|
+
function generate(ctx, route) {
|
|
648
|
+
const lineage = getRouteLineage(ctx.config.routes, route);
|
|
649
|
+
const urlpath = lineage.map((route2) => route2.path).join("/");
|
|
650
|
+
const typesPath = getTypesPath(ctx, route);
|
|
651
|
+
const parents = lineage.slice(0, -1);
|
|
652
|
+
const parentTypeImports = parents.map((parent, i) => {
|
|
653
|
+
const rel = Path3.relative(
|
|
654
|
+
Path3.dirname(typesPath),
|
|
655
|
+
getTypesPath(ctx, parent)
|
|
656
|
+
);
|
|
657
|
+
const indent = i === 0 ? "" : " ".repeat(2);
|
|
658
|
+
let source = noExtension(rel);
|
|
659
|
+
if (!source.startsWith("../")) source = "./" + source;
|
|
660
|
+
return `${indent}import type { Info as Parent${i} } from "${source}.js"`;
|
|
661
|
+
}).join("\n");
|
|
629
662
|
return import_dedent.default`
|
|
630
663
|
// React Router generated types for route:
|
|
631
664
|
// ${route.file}
|
|
632
665
|
|
|
633
|
-
import type
|
|
666
|
+
import type * as T from "react-router/route-module"
|
|
667
|
+
|
|
668
|
+
${parentTypeImports}
|
|
634
669
|
|
|
635
|
-
type
|
|
636
|
-
export type Info = Routes[RouteId];
|
|
670
|
+
type Module = typeof import("../${Pathe2.filename(route.file)}.js")
|
|
637
671
|
|
|
638
|
-
type
|
|
672
|
+
export type Info = {
|
|
673
|
+
parents: [${parents.map((_, i) => `Parent${i}`).join(", ")}],
|
|
674
|
+
id: "${route.id}"
|
|
675
|
+
file: "${route.file}"
|
|
676
|
+
path: "${route.path}"
|
|
677
|
+
params: {${formatParamProperties(
|
|
678
|
+
urlpath
|
|
679
|
+
)}} & { [key: string]: string | undefined }
|
|
680
|
+
module: Module
|
|
681
|
+
loaderData: T.CreateLoaderData<Module>
|
|
682
|
+
actionData: T.CreateActionData<Module>
|
|
683
|
+
}
|
|
639
684
|
|
|
640
685
|
export namespace Route {
|
|
641
|
-
export type LinkDescriptors =
|
|
642
|
-
export type LinksFunction = () => LinkDescriptors
|
|
686
|
+
export type LinkDescriptors = T.LinkDescriptors
|
|
687
|
+
export type LinksFunction = () => LinkDescriptors
|
|
643
688
|
|
|
644
|
-
export type MetaArgs =
|
|
645
|
-
export type MetaDescriptors =
|
|
646
|
-
export type MetaFunction = (args: MetaArgs) => MetaDescriptors
|
|
689
|
+
export type MetaArgs = T.CreateMetaArgs<Info>
|
|
690
|
+
export type MetaDescriptors = T.MetaDescriptors
|
|
691
|
+
export type MetaFunction = (args: MetaArgs) => MetaDescriptors
|
|
647
692
|
|
|
648
|
-
export type HeadersArgs =
|
|
649
|
-
export type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit
|
|
693
|
+
export type HeadersArgs = T.HeadersArgs
|
|
694
|
+
export type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit
|
|
650
695
|
|
|
651
|
-
export type LoaderArgs =
|
|
652
|
-
export type ClientLoaderArgs =
|
|
653
|
-
export type ActionArgs =
|
|
654
|
-
export type ClientActionArgs =
|
|
696
|
+
export type LoaderArgs = T.CreateServerLoaderArgs<Info>
|
|
697
|
+
export type ClientLoaderArgs = T.CreateClientLoaderArgs<Info>
|
|
698
|
+
export type ActionArgs = T.CreateServerActionArgs<Info>
|
|
699
|
+
export type ClientActionArgs = T.CreateClientActionArgs<Info>
|
|
655
700
|
|
|
656
|
-
export type HydrateFallbackProps =
|
|
657
|
-
export type ComponentProps =
|
|
658
|
-
export type ErrorBoundaryProps =
|
|
701
|
+
export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Info>
|
|
702
|
+
export type ComponentProps = T.CreateComponentProps<Info>
|
|
703
|
+
export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Info>
|
|
659
704
|
}
|
|
660
705
|
`;
|
|
661
706
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
707
|
+
var noExtension = (path7) => Path3.join(Path3.dirname(path7), Pathe2.filename(path7));
|
|
708
|
+
function getRouteLineage(routes, route) {
|
|
709
|
+
const result = [];
|
|
710
|
+
while (route) {
|
|
711
|
+
result.push(route);
|
|
712
|
+
if (!route.parentId) break;
|
|
713
|
+
route = routes[route.parentId];
|
|
714
|
+
}
|
|
715
|
+
result.reverse();
|
|
716
|
+
return result;
|
|
668
717
|
}
|
|
669
|
-
function
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
718
|
+
function formatParamProperties(urlpath) {
|
|
719
|
+
const params = parseParams(urlpath);
|
|
720
|
+
const properties = Object.entries(params).map(([name, values]) => {
|
|
721
|
+
if (values.length === 1) {
|
|
722
|
+
const isOptional = values[0];
|
|
723
|
+
return isOptional ? `"${name}"?: string` : `"${name}": string`;
|
|
724
|
+
}
|
|
725
|
+
const items = values.map(
|
|
726
|
+
(isOptional) => isOptional ? "string | undefined" : "string"
|
|
727
|
+
);
|
|
728
|
+
return `"${name}": [${items.join(", ")}]`;
|
|
729
|
+
});
|
|
730
|
+
return properties.join("; ");
|
|
731
|
+
}
|
|
732
|
+
function parseParams(urlpath) {
|
|
733
|
+
const result = {};
|
|
734
|
+
let segments = urlpath.split("/");
|
|
735
|
+
segments.forEach((segment) => {
|
|
736
|
+
const match = segment.match(/^:([\w-]+)(\?)?/);
|
|
737
|
+
if (!match) return;
|
|
738
|
+
const param = match[1];
|
|
739
|
+
const isOptional = match[2] !== void 0;
|
|
740
|
+
result[param] ??= [];
|
|
741
|
+
result[param].push(isOptional);
|
|
742
|
+
return;
|
|
743
|
+
});
|
|
744
|
+
const hasSplat = segments.at(-1) === "*";
|
|
745
|
+
if (hasSplat) result["*"] = [false];
|
|
746
|
+
return result;
|
|
676
747
|
}
|
|
677
748
|
|
|
678
749
|
// typegen/index.ts
|
|
@@ -714,97 +785,16 @@ async function createContext2({
|
|
|
714
785
|
config
|
|
715
786
|
};
|
|
716
787
|
}
|
|
717
|
-
function asJS(path7) {
|
|
718
|
-
return path7.replace(/\.(js|ts)x?$/, ".js");
|
|
719
|
-
}
|
|
720
|
-
function formatRoute(ctx, { id, path: path7, file, parentId }) {
|
|
721
|
-
const modulePath = Path3.relative(
|
|
722
|
-
ctx.rootDirectory,
|
|
723
|
-
Path3.join(ctx.config.appDirectory, file)
|
|
724
|
-
);
|
|
725
|
-
return [
|
|
726
|
-
`"${id}": {`,
|
|
727
|
-
` parentId: ${JSON.stringify(parentId)}`,
|
|
728
|
-
` path: ${JSON.stringify(path7)}`,
|
|
729
|
-
` module: typeof import("${asJS(modulePath)}")`,
|
|
730
|
-
`}`
|
|
731
|
-
].map((line) => ` ${line}`).join("\n");
|
|
732
|
-
}
|
|
733
788
|
async function writeAll(ctx) {
|
|
734
|
-
let routes = Object.values(ctx.config.routes);
|
|
735
|
-
let pathsToParams = /* @__PURE__ */ new Map();
|
|
736
|
-
for (let route of routes) {
|
|
737
|
-
if (route.path === void 0) continue;
|
|
738
|
-
let lineage = getRouteLineage(ctx.config.routes, route);
|
|
739
|
-
let path7 = lineage.filter((route2) => route2.path !== void 0).map((route2) => route2.path).join("/");
|
|
740
|
-
if (path7 === "") path7 = "/";
|
|
741
|
-
pathsToParams.set(path7, parseParams(path7));
|
|
742
|
-
}
|
|
743
|
-
let formattedPaths = `type Paths = {`;
|
|
744
|
-
for (let [path7, params] of pathsToParams.entries()) {
|
|
745
|
-
let formattedParams = Object.entries(params).map(
|
|
746
|
-
([param, required]) => `"${param}"${required ? "" : "?"}: string`
|
|
747
|
-
);
|
|
748
|
-
let formattedEntry = `"${path7}": {${formattedParams.join(",")}},
|
|
749
|
-
`;
|
|
750
|
-
formattedPaths += formattedEntry;
|
|
751
|
-
}
|
|
752
|
-
formattedPaths += `}`;
|
|
753
789
|
const typegenDir = getTypesDir(ctx);
|
|
754
790
|
import_node_fs2.default.rmSync(typegenDir, { recursive: true, force: true });
|
|
755
|
-
const newTypes = Path3.join(typegenDir, "routes.ts");
|
|
756
|
-
import_node_fs2.default.mkdirSync(Path3.dirname(newTypes), { recursive: true });
|
|
757
|
-
import_node_fs2.default.writeFileSync(
|
|
758
|
-
newTypes,
|
|
759
|
-
formattedPaths + `
|
|
760
|
-
|
|
761
|
-
type Routes = {
|
|
762
|
-
${routes.map((route) => formatRoute(ctx, route)).join("\n")}
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
` + import_dedent2.default`
|
|
766
|
-
declare module "react-router/types" {
|
|
767
|
-
interface Register {
|
|
768
|
-
paths: Paths
|
|
769
|
-
routes: Routes
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
export {}
|
|
774
|
-
`
|
|
775
|
-
);
|
|
776
791
|
Object.values(ctx.config.routes).forEach((route) => {
|
|
777
792
|
const typesPath = getTypesPath(ctx, route);
|
|
778
|
-
const content = generate(route);
|
|
779
|
-
import_node_fs2.default.mkdirSync(
|
|
793
|
+
const content = generate(ctx, route);
|
|
794
|
+
import_node_fs2.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
|
|
780
795
|
import_node_fs2.default.writeFileSync(typesPath, content);
|
|
781
796
|
});
|
|
782
797
|
}
|
|
783
|
-
function getRouteLineage(routes, route) {
|
|
784
|
-
const result = [];
|
|
785
|
-
while (route) {
|
|
786
|
-
result.push(route);
|
|
787
|
-
if (!route.parentId) break;
|
|
788
|
-
route = routes[route.parentId];
|
|
789
|
-
}
|
|
790
|
-
result.reverse();
|
|
791
|
-
return result;
|
|
792
|
-
}
|
|
793
|
-
function parseParams(urlpath) {
|
|
794
|
-
const result = {};
|
|
795
|
-
let segments = urlpath.split("/");
|
|
796
|
-
segments.forEach((segment) => {
|
|
797
|
-
const match = segment.match(/^:([\w-]+)(\?)?/);
|
|
798
|
-
if (!match) return;
|
|
799
|
-
const param = match[1];
|
|
800
|
-
const isRequired = match[2] === void 0;
|
|
801
|
-
result[param] ||= isRequired;
|
|
802
|
-
return;
|
|
803
|
-
});
|
|
804
|
-
const hasSplat = segments.at(-1) === "*";
|
|
805
|
-
if (hasSplat) result["*"] = true;
|
|
806
|
-
return result;
|
|
807
|
-
}
|
|
808
798
|
|
|
809
799
|
// vite/babel.ts
|
|
810
800
|
var import_parser = require("@babel/parser");
|
|
@@ -1170,8 +1160,613 @@ function invalidDestructureError(name) {
|
|
|
1170
1160
|
return new Error(`Cannot remove destructured export "${name}"`);
|
|
1171
1161
|
}
|
|
1172
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
|
+
|
|
1173
1768
|
// vite/with-props.ts
|
|
1174
|
-
var
|
|
1769
|
+
var import_dedent2 = __toESM(require("dedent"));
|
|
1175
1770
|
var vmod = create("with-props");
|
|
1176
1771
|
var NAMED_COMPONENT_EXPORTS = ["HydrateFallback", "ErrorBoundary"];
|
|
1177
1772
|
var plugin = {
|
|
@@ -1182,7 +1777,7 @@ var plugin = {
|
|
|
1182
1777
|
},
|
|
1183
1778
|
async load(id) {
|
|
1184
1779
|
if (id !== vmod.resolvedId) return;
|
|
1185
|
-
return
|
|
1780
|
+
return import_dedent2.default`
|
|
1186
1781
|
import { createElement as h } from "react";
|
|
1187
1782
|
import { useActionData, useLoaderData, useMatches, useParams, useRouteError } from "react-router";
|
|
1188
1783
|
|
|
@@ -1309,8 +1904,20 @@ var CLIENT_ROUTE_EXPORTS = [
|
|
|
1309
1904
|
"shouldRevalidate"
|
|
1310
1905
|
];
|
|
1311
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
|
+
};
|
|
1312
1913
|
var virtualHmrRuntime = create("hmr-runtime");
|
|
1313
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
|
+
};
|
|
1314
1921
|
var resolveRelativeRouteFilePath = (route, reactRouterConfig) => {
|
|
1315
1922
|
let vite2 = getVite();
|
|
1316
1923
|
let file = route.file;
|
|
@@ -1339,23 +1946,35 @@ var resolveChunk = (ctx, viteManifest, absoluteFilePath) => {
|
|
|
1339
1946
|
let rootRelativeFilePath = vite2.normalizePath(
|
|
1340
1947
|
path6.relative(ctx.rootDirectory, absoluteFilePath)
|
|
1341
1948
|
);
|
|
1342
|
-
let entryChunk = viteManifest[rootRelativeFilePath
|
|
1949
|
+
let entryChunk = viteManifest[rootRelativeFilePath];
|
|
1343
1950
|
if (!entryChunk) {
|
|
1344
|
-
|
|
1345
|
-
throw new Error(
|
|
1346
|
-
`No manifest entry found for "${rootRelativeFilePath}". Known manifest keys: ${knownManifestKeys}`
|
|
1347
|
-
);
|
|
1951
|
+
return void 0;
|
|
1348
1952
|
}
|
|
1349
1953
|
return entryChunk;
|
|
1350
1954
|
};
|
|
1955
|
+
var getPublicModulePathForEntry = (ctx, viteManifest, entryFilePath) => {
|
|
1956
|
+
let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
|
|
1957
|
+
return entryChunk ? `${ctx.publicPath}${entryChunk.file}` : void 0;
|
|
1958
|
+
};
|
|
1351
1959
|
var getReactRouterManifestBuildAssets = (ctx, viteManifest, entryFilePath, prependedAssetFilePaths = []) => {
|
|
1352
1960
|
let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
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);
|
|
1356
1974
|
let chunks = resolveDependantChunks(viteManifest, [
|
|
1357
1975
|
...prependedAssetChunks,
|
|
1358
|
-
entryChunk
|
|
1976
|
+
entryChunk,
|
|
1977
|
+
...routeModuleChunks
|
|
1359
1978
|
]);
|
|
1360
1979
|
return {
|
|
1361
1980
|
module: `${ctx.publicPath}${entryChunk.file}`,
|
|
@@ -1392,6 +2011,10 @@ var writeFileSafe = async (file, contents) => {
|
|
|
1392
2011
|
await fse.ensureDir(path6.dirname(file));
|
|
1393
2012
|
await fse.writeFile(file, contents);
|
|
1394
2013
|
};
|
|
2014
|
+
var getExportNames = (code) => {
|
|
2015
|
+
let [, exportSpecifiers] = (0, import_es_module_lexer.parse)(code);
|
|
2016
|
+
return exportSpecifiers.map(({ n: name }) => name);
|
|
2017
|
+
};
|
|
1395
2018
|
var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
|
|
1396
2019
|
let entries = await Promise.all(
|
|
1397
2020
|
Object.entries(ctx.reactRouterConfig.routes).map(async ([key, route]) => {
|
|
@@ -1405,7 +2028,7 @@ var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
|
|
|
1405
2028
|
);
|
|
1406
2029
|
return Object.fromEntries(entries);
|
|
1407
2030
|
};
|
|
1408
|
-
var
|
|
2031
|
+
var compileRouteFile = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
|
|
1409
2032
|
if (!viteChildCompiler) {
|
|
1410
2033
|
throw new Error("Vite child compiler not found");
|
|
1411
2034
|
}
|
|
@@ -1425,9 +2048,19 @@ var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteF
|
|
|
1425
2048
|
moduleGraph.ensureEntryFromUrl(url2, ssr)
|
|
1426
2049
|
]);
|
|
1427
2050
|
let transformed = await pluginContainer.transform(code, id, { ssr });
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
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);
|
|
1431
2064
|
};
|
|
1432
2065
|
var getServerBundleBuildConfig = (viteUserConfig) => {
|
|
1433
2066
|
if (!("__reactRouterServerBundleBuildConfig" in viteUserConfig) || !viteUserConfig.__reactRouterServerBundleBuildConfig) {
|
|
@@ -1447,7 +2080,7 @@ var defaultEntriesDir = path6.resolve(
|
|
|
1447
2080
|
"config",
|
|
1448
2081
|
"defaults"
|
|
1449
2082
|
);
|
|
1450
|
-
var defaultEntries = fse.readdirSync(defaultEntriesDir).map((
|
|
2083
|
+
var defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path6.join(defaultEntriesDir, filename3));
|
|
1451
2084
|
invariant(defaultEntries.length > 0, "No default entries found");
|
|
1452
2085
|
var reactRouterDevLoadContext = () => ({});
|
|
1453
2086
|
var reactRouterVitePlugin = () => {
|
|
@@ -1458,6 +2091,7 @@ var reactRouterVitePlugin = () => {
|
|
|
1458
2091
|
let viteConfig;
|
|
1459
2092
|
let cssModulesManifest = {};
|
|
1460
2093
|
let viteChildCompiler = null;
|
|
2094
|
+
let cache = /* @__PURE__ */ new Map();
|
|
1461
2095
|
let reactRouterConfigLoader;
|
|
1462
2096
|
let typegenWatcherPromise;
|
|
1463
2097
|
let logger;
|
|
@@ -1597,13 +2231,31 @@ var reactRouterVitePlugin = () => {
|
|
|
1597
2231
|
viteChildCompiler,
|
|
1598
2232
|
ctx
|
|
1599
2233
|
);
|
|
2234
|
+
let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
|
|
1600
2235
|
for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
|
|
1601
|
-
let
|
|
1602
|
-
ctx.reactRouterConfig.appDirectory,
|
|
1603
|
-
route.file
|
|
1604
|
-
);
|
|
2236
|
+
let routeFile = path6.join(ctx.reactRouterConfig.appDirectory, route.file);
|
|
1605
2237
|
let sourceExports = routeManifestExports[key];
|
|
1606
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
|
+
}
|
|
1607
2259
|
let routeManifestEntry = {
|
|
1608
2260
|
id: route.id,
|
|
1609
2261
|
parentId: route.parentId,
|
|
@@ -1612,18 +2264,33 @@ var reactRouterVitePlugin = () => {
|
|
|
1612
2264
|
caseSensitive: route.caseSensitive,
|
|
1613
2265
|
hasAction: sourceExports.includes("action"),
|
|
1614
2266
|
hasLoader: sourceExports.includes("loader"),
|
|
1615
|
-
hasClientAction
|
|
1616
|
-
hasClientLoader
|
|
2267
|
+
hasClientAction,
|
|
2268
|
+
hasClientLoader,
|
|
1617
2269
|
hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
|
|
1618
2270
|
...getReactRouterManifestBuildAssets(
|
|
1619
2271
|
ctx,
|
|
1620
2272
|
viteManifest,
|
|
1621
|
-
|
|
2273
|
+
`${routeFile}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
|
|
1622
2274
|
// If this is the root route, we also need to include assets from the
|
|
1623
2275
|
// client entry file as this is a common way for consumers to import
|
|
1624
2276
|
// global reset styles, etc.
|
|
1625
2277
|
isRootRoute ? [ctx.entryClientFilePath] : []
|
|
1626
|
-
)
|
|
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
|
|
1627
2294
|
};
|
|
1628
2295
|
browserRoutes[key] = routeManifestEntry;
|
|
1629
2296
|
let serverBundleRoutes = ctx.serverBundleBuildConfig?.routes;
|
|
@@ -1664,25 +2331,52 @@ var reactRouterVitePlugin = () => {
|
|
|
1664
2331
|
viteChildCompiler,
|
|
1665
2332
|
ctx
|
|
1666
2333
|
);
|
|
2334
|
+
let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
|
|
1667
2335
|
for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
|
|
2336
|
+
let routeFile = route.file;
|
|
1668
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
|
+
}
|
|
1669
2365
|
routes[key] = {
|
|
1670
2366
|
id: route.id,
|
|
1671
2367
|
parentId: route.parentId,
|
|
1672
2368
|
path: route.path,
|
|
1673
2369
|
index: route.index,
|
|
1674
2370
|
caseSensitive: route.caseSensitive,
|
|
1675
|
-
module:
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
)
|
|
1681
|
-
),
|
|
2371
|
+
module: routeModulePath,
|
|
2372
|
+
// Split route modules are a build-time optimization
|
|
2373
|
+
clientActionModule: void 0,
|
|
2374
|
+
clientLoaderModule: void 0,
|
|
2375
|
+
hydrateFallbackModule: void 0,
|
|
1682
2376
|
hasAction: sourceExports.includes("action"),
|
|
1683
2377
|
hasLoader: sourceExports.includes("loader"),
|
|
1684
|
-
hasClientAction
|
|
1685
|
-
hasClientLoader
|
|
2378
|
+
hasClientAction,
|
|
2379
|
+
hasClientLoader,
|
|
1686
2380
|
hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
|
|
1687
2381
|
imports: []
|
|
1688
2382
|
};
|
|
@@ -1715,8 +2409,13 @@ var reactRouterVitePlugin = () => {
|
|
|
1715
2409
|
let viteClientConditions = [
|
|
1716
2410
|
...vite2.defaultClientConditions ?? []
|
|
1717
2411
|
];
|
|
2412
|
+
let packageRoot = path6.dirname(
|
|
2413
|
+
require.resolve("@react-router/dev/package.json")
|
|
2414
|
+
);
|
|
2415
|
+
let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
|
|
1718
2416
|
let viteServerConditions = [
|
|
1719
|
-
...vite2.defaultServerConditions ?? []
|
|
2417
|
+
...vite2.defaultServerConditions ?? [],
|
|
2418
|
+
...moduleSyncEnabled ? ["module-sync"] : []
|
|
1720
2419
|
];
|
|
1721
2420
|
logger = vite2.createLogger(viteUserConfig.logLevel, {
|
|
1722
2421
|
prefix: "[react-router]"
|
|
@@ -1773,9 +2472,9 @@ var reactRouterVitePlugin = () => {
|
|
|
1773
2472
|
},
|
|
1774
2473
|
optimizeDeps: {
|
|
1775
2474
|
entries: ctx.reactRouterConfig.future.unstable_optimizeDeps ? [
|
|
1776
|
-
ctx.entryClientFilePath,
|
|
2475
|
+
vite2.normalizePath(ctx.entryClientFilePath),
|
|
1777
2476
|
...Object.values(ctx.reactRouterConfig.routes).map(
|
|
1778
|
-
(route) =>
|
|
2477
|
+
(route) => resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
1779
2478
|
)
|
|
1780
2479
|
] : [],
|
|
1781
2480
|
include: [
|
|
@@ -1830,12 +2529,28 @@ var reactRouterVitePlugin = () => {
|
|
|
1830
2529
|
preserveEntrySignatures: "exports-only",
|
|
1831
2530
|
input: [
|
|
1832
2531
|
ctx.entryClientFilePath,
|
|
1833
|
-
...Object.values(
|
|
1834
|
-
|
|
2532
|
+
...Object.values(
|
|
2533
|
+
ctx.reactRouterConfig.routes
|
|
2534
|
+
).flatMap((route) => {
|
|
2535
|
+
let routeFilePath = path6.resolve(
|
|
1835
2536
|
ctx.reactRouterConfig.appDirectory,
|
|
1836
2537
|
route.file
|
|
1837
|
-
)
|
|
1838
|
-
|
|
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
|
+
})
|
|
1839
2554
|
]
|
|
1840
2555
|
}
|
|
1841
2556
|
} : {
|
|
@@ -2073,6 +2788,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2073
2788
|
viteConfig,
|
|
2074
2789
|
ctx.reactRouterConfig,
|
|
2075
2790
|
serverBuildDirectory,
|
|
2791
|
+
ssrViteManifest[virtual.serverBuild.id].file,
|
|
2076
2792
|
clientBuildDirectory
|
|
2077
2793
|
);
|
|
2078
2794
|
}
|
|
@@ -2081,6 +2797,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2081
2797
|
viteConfig,
|
|
2082
2798
|
ctx.reactRouterConfig,
|
|
2083
2799
|
serverBuildDirectory,
|
|
2800
|
+
ssrViteManifest[virtual.serverBuild.id].file,
|
|
2084
2801
|
clientBuildDirectory
|
|
2085
2802
|
);
|
|
2086
2803
|
}
|
|
@@ -2103,10 +2820,59 @@ var reactRouterVitePlugin = () => {
|
|
|
2103
2820
|
await typegenWatcher?.close();
|
|
2104
2821
|
}
|
|
2105
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
|
+
},
|
|
2106
2873
|
{
|
|
2107
2874
|
name: "react-router:build-client-route",
|
|
2108
|
-
|
|
2109
|
-
async transform(_code, id, options) {
|
|
2875
|
+
async transform(code, id, options) {
|
|
2110
2876
|
if (!id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING)) return;
|
|
2111
2877
|
let routeModuleId = id.replace(BUILD_CLIENT_ROUTE_QUERY_STRING, "");
|
|
2112
2878
|
let routeFileName = path6.basename(routeModuleId);
|
|
@@ -2115,12 +2881,59 @@ var reactRouterVitePlugin = () => {
|
|
|
2115
2881
|
ctx,
|
|
2116
2882
|
routeModuleId
|
|
2117
2883
|
);
|
|
2118
|
-
let
|
|
2119
|
-
|
|
2120
|
-
|
|
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(", ");
|
|
2121
2892
|
return `export { ${reexports} } from "./${routeFileName}";`;
|
|
2122
2893
|
}
|
|
2123
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
|
+
},
|
|
2124
2937
|
{
|
|
2125
2938
|
name: "react-router:virtual-modules",
|
|
2126
2939
|
enforce: "pre",
|
|
@@ -2175,8 +2988,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2175
2988
|
let importerShort = vite2.normalizePath(
|
|
2176
2989
|
path6.relative(ctx.rootDirectory, importer)
|
|
2177
2990
|
);
|
|
2178
|
-
|
|
2179
|
-
if (isRoute) {
|
|
2991
|
+
if (isRoute(ctx.reactRouterConfig, importer)) {
|
|
2180
2992
|
let serverOnlyExports = SERVER_ONLY_ROUTE_EXPORTS.map(
|
|
2181
2993
|
(xport) => `\`${xport}\``
|
|
2182
2994
|
).join(", ");
|
|
@@ -2215,10 +3027,10 @@ var reactRouterVitePlugin = () => {
|
|
|
2215
3027
|
let clientFileRE = /\.client(\.[cm]?[jt]sx?)?$/;
|
|
2216
3028
|
let clientDirRE = /\/\.client\//;
|
|
2217
3029
|
if (clientFileRE.test(id) || clientDirRE.test(id)) {
|
|
2218
|
-
let exports2 = (
|
|
3030
|
+
let exports2 = getExportNames(code);
|
|
2219
3031
|
return {
|
|
2220
3032
|
code: exports2.map(
|
|
2221
|
-
(
|
|
3033
|
+
(name) => name === "default" ? "export default undefined;" : `export const ${name} = undefined;`
|
|
2222
3034
|
).join("\n"),
|
|
2223
3035
|
map: null
|
|
2224
3036
|
};
|
|
@@ -2229,17 +3041,25 @@ var reactRouterVitePlugin = () => {
|
|
|
2229
3041
|
{
|
|
2230
3042
|
name: "react-router:route-exports",
|
|
2231
3043
|
async transform(code, id, options) {
|
|
3044
|
+
if (isRouteChunkModuleId(id)) {
|
|
3045
|
+
id = id.split("?")[0];
|
|
3046
|
+
}
|
|
2232
3047
|
let route = getRoute(ctx.reactRouterConfig, id);
|
|
2233
3048
|
if (!route) return;
|
|
2234
3049
|
if (!options?.ssr && !ctx.reactRouterConfig.ssr) {
|
|
2235
|
-
let
|
|
3050
|
+
let exportNames = getExportNames(code);
|
|
3051
|
+
let serverOnlyExports = exportNames.filter(
|
|
3052
|
+
(exp) => SERVER_ONLY_ROUTE_EXPORTS.includes(exp)
|
|
3053
|
+
);
|
|
2236
3054
|
if (serverOnlyExports.length > 0) {
|
|
2237
3055
|
let str = serverOnlyExports.map((e) => `\`${e}\``).join(", ");
|
|
2238
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.`;
|
|
2239
3057
|
throw Error(message);
|
|
2240
3058
|
}
|
|
2241
3059
|
if (route.id !== "root") {
|
|
2242
|
-
let hasHydrateFallback =
|
|
3060
|
+
let hasHydrateFallback = exportNames.some(
|
|
3061
|
+
(exp) => exp === "HydrateFallback"
|
|
3062
|
+
);
|
|
2243
3063
|
if (hasHydrateFallback) {
|
|
2244
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.`;
|
|
2245
3065
|
throw Error(message);
|
|
@@ -2317,6 +3137,9 @@ var reactRouterVitePlugin = () => {
|
|
|
2317
3137
|
let isJSX = filepath.endsWith("x");
|
|
2318
3138
|
let useFastRefresh = !ssr && (isJSX || code.includes(devRuntime));
|
|
2319
3139
|
if (!useFastRefresh) return;
|
|
3140
|
+
if (isRouteVirtualModule(id)) {
|
|
3141
|
+
return { code: addRefreshWrapper(ctx.reactRouterConfig, code, id) };
|
|
3142
|
+
}
|
|
2320
3143
|
let result = await babel.transformAsync(code, {
|
|
2321
3144
|
babelrc: false,
|
|
2322
3145
|
configFile: false,
|
|
@@ -2347,6 +3170,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2347
3170
|
let serverManifest = (await server.ssrLoadModule(virtual.serverManifest.id)).default;
|
|
2348
3171
|
let oldRouteMetadata = serverManifest.routes[route.id];
|
|
2349
3172
|
let newRouteMetadata = await getRouteMetadata(
|
|
3173
|
+
cache,
|
|
2350
3174
|
ctx,
|
|
2351
3175
|
viteChildCompiler,
|
|
2352
3176
|
route,
|
|
@@ -2356,9 +3180,12 @@ var reactRouterVitePlugin = () => {
|
|
|
2356
3180
|
if (!oldRouteMetadata || [
|
|
2357
3181
|
"hasLoader",
|
|
2358
3182
|
"hasClientLoader",
|
|
3183
|
+
"clientLoaderModule",
|
|
2359
3184
|
"hasAction",
|
|
2360
3185
|
"hasClientAction",
|
|
2361
|
-
"
|
|
3186
|
+
"clientActionModule",
|
|
3187
|
+
"hasErrorBoundary",
|
|
3188
|
+
"hydrateFallbackModule"
|
|
2362
3189
|
].some((key) => oldRouteMetadata[key] !== newRouteMetadata[key])) {
|
|
2363
3190
|
invalidateVirtualModules(server);
|
|
2364
3191
|
}
|
|
@@ -2476,13 +3303,30 @@ function getRoute(pluginConfig, file) {
|
|
|
2476
3303
|
);
|
|
2477
3304
|
return route;
|
|
2478
3305
|
}
|
|
2479
|
-
|
|
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:
|
|
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"),
|
|
@@ -2513,11 +3354,8 @@ async function getRouteMetadata(ctx, viteChildCompiler, route, readRouteFile) {
|
|
|
2513
3354
|
};
|
|
2514
3355
|
return info;
|
|
2515
3356
|
}
|
|
2516
|
-
async function getPrerenderBuildAndHandler(viteConfig,
|
|
2517
|
-
let serverBuildPath = path6.join(
|
|
2518
|
-
serverBuildDirectory,
|
|
2519
|
-
reactRouterConfig.serverBuildFile
|
|
2520
|
-
);
|
|
3357
|
+
async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, serverBuildFile) {
|
|
3358
|
+
let serverBuildPath = path6.join(serverBuildDirectory, serverBuildFile);
|
|
2521
3359
|
let build = await import(url.pathToFileURL(serverBuildPath).toString());
|
|
2522
3360
|
let { createRequestHandler: createHandler } = await import("react-router");
|
|
2523
3361
|
return {
|
|
@@ -2525,11 +3363,11 @@ async function getPrerenderBuildAndHandler(viteConfig, reactRouterConfig, server
|
|
|
2525
3363
|
handler: createHandler(build, viteConfig.mode)
|
|
2526
3364
|
};
|
|
2527
3365
|
}
|
|
2528
|
-
async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory, clientBuildDirectory) {
|
|
3366
|
+
async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildFile, clientBuildDirectory) {
|
|
2529
3367
|
let { handler } = await getPrerenderBuildAndHandler(
|
|
2530
3368
|
viteConfig,
|
|
2531
|
-
|
|
2532
|
-
|
|
3369
|
+
serverBuildDirectory,
|
|
3370
|
+
serverBuildFile
|
|
2533
3371
|
);
|
|
2534
3372
|
let request = new Request(`http://localhost${reactRouterConfig.basename}`);
|
|
2535
3373
|
let response = await handler(request);
|
|
@@ -2541,11 +3379,11 @@ async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory
|
|
|
2541
3379
|
"SPA Mode: index.html has been written to your " + import_picocolors3.default.bold(path6.relative(process.cwd(), clientBuildDirectory)) + " directory"
|
|
2542
3380
|
);
|
|
2543
3381
|
}
|
|
2544
|
-
async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirectory, clientBuildDirectory) {
|
|
3382
|
+
async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildPath, clientBuildDirectory) {
|
|
2545
3383
|
let { build, handler } = await getPrerenderBuildAndHandler(
|
|
2546
3384
|
viteConfig,
|
|
2547
|
-
|
|
2548
|
-
|
|
3385
|
+
serverBuildDirectory,
|
|
3386
|
+
serverBuildPath
|
|
2549
3387
|
);
|
|
2550
3388
|
let routes = createPrerenderRoutes(build.routes);
|
|
2551
3389
|
let routesToPrerender;
|
|
@@ -2752,6 +3590,73 @@ function createPrerenderRoutes(manifest, parentId = "", routesByParentId = group
|
|
|
2752
3590
|
};
|
|
2753
3591
|
});
|
|
2754
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
|
+
}
|
|
2755
3660
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2756
3661
|
0 && (module.exports = {
|
|
2757
3662
|
reactRouter
|