@react-router/dev 0.0.0-experimental-a2c4d7fad → 0.0.0-experimental-902325fda
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/cli/index.js +64 -122
- package/dist/config.js +1 -1
- package/dist/routes.js +1 -1
- package/dist/static/refresh-utils.cjs +1 -1
- package/dist/vite/cloudflare.js +1 -1
- package/dist/vite.js +214 -188
- package/package.json +6 -6
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @react-router/dev v0.0.0-experimental-
|
|
3
|
+
* @react-router/dev v0.0.0-experimental-902325fda
|
|
4
4
|
*
|
|
5
5
|
* Copyright (c) Remix Software Inc.
|
|
6
6
|
*
|
|
@@ -635,25 +635,6 @@ var init_profiler = __esm({
|
|
|
635
635
|
}
|
|
636
636
|
});
|
|
637
637
|
|
|
638
|
-
// vite/babel.ts
|
|
639
|
-
var babel_exports = {};
|
|
640
|
-
__export(babel_exports, {
|
|
641
|
-
generate: () => generate,
|
|
642
|
-
parse: () => import_parser.parse,
|
|
643
|
-
t: () => t,
|
|
644
|
-
traverse: () => traverse
|
|
645
|
-
});
|
|
646
|
-
var import_parser, t, traverse, generate;
|
|
647
|
-
var init_babel = __esm({
|
|
648
|
-
"vite/babel.ts"() {
|
|
649
|
-
"use strict";
|
|
650
|
-
import_parser = require("@babel/parser");
|
|
651
|
-
t = __toESM(require("@babel/types"));
|
|
652
|
-
traverse = require("@babel/traverse").default;
|
|
653
|
-
generate = require("@babel/generator").default;
|
|
654
|
-
}
|
|
655
|
-
});
|
|
656
|
-
|
|
657
638
|
// typegen/paths.ts
|
|
658
639
|
function getTypesDir(ctx) {
|
|
659
640
|
return Path2.join(ctx.rootDirectory, ".react-router/types");
|
|
@@ -676,8 +657,9 @@ var init_paths = __esm({
|
|
|
676
657
|
});
|
|
677
658
|
|
|
678
659
|
// typegen/generate.ts
|
|
679
|
-
function
|
|
660
|
+
function generate(ctx, route) {
|
|
680
661
|
const lineage = getRouteLineage(ctx.config.routes, route);
|
|
662
|
+
const urlpath = lineage.map((route2) => route2.path).join("/");
|
|
681
663
|
const typesPath = getTypesPath(ctx, route);
|
|
682
664
|
const parents = lineage.slice(0, -1);
|
|
683
665
|
const parentTypeImports = parents.map((parent, i) => {
|
|
@@ -695,15 +677,22 @@ function generate2(ctx, route) {
|
|
|
695
677
|
// ${route.file}
|
|
696
678
|
|
|
697
679
|
import type * as T from "react-router/route-module"
|
|
698
|
-
import type { Routes } from "react-router/types"
|
|
699
680
|
|
|
700
681
|
${parentTypeImports}
|
|
701
682
|
|
|
702
|
-
type
|
|
683
|
+
type Module = typeof import("../${Pathe2.filename(route.file)}.js")
|
|
703
684
|
|
|
704
|
-
export type Info =
|
|
685
|
+
export type Info = {
|
|
705
686
|
parents: [${parents.map((_, i) => `Parent${i}`).join(", ")}],
|
|
706
|
-
id:
|
|
687
|
+
id: "${route.id}"
|
|
688
|
+
file: "${route.file}"
|
|
689
|
+
path: "${route.path}"
|
|
690
|
+
params: {${formatParamProperties(
|
|
691
|
+
urlpath
|
|
692
|
+
)}} & { [key: string]: string | undefined }
|
|
693
|
+
module: Module
|
|
694
|
+
loaderData: T.CreateLoaderData<Module>
|
|
695
|
+
actionData: T.CreateActionData<Module>
|
|
707
696
|
}
|
|
708
697
|
|
|
709
698
|
export namespace Route {
|
|
@@ -738,6 +727,36 @@ function getRouteLineage(routes2, route) {
|
|
|
738
727
|
result.reverse();
|
|
739
728
|
return result;
|
|
740
729
|
}
|
|
730
|
+
function formatParamProperties(urlpath) {
|
|
731
|
+
const params = parseParams(urlpath);
|
|
732
|
+
const properties = Object.entries(params).map(([name, values]) => {
|
|
733
|
+
if (values.length === 1) {
|
|
734
|
+
const isOptional = values[0];
|
|
735
|
+
return isOptional ? `"${name}"?: string` : `"${name}": string`;
|
|
736
|
+
}
|
|
737
|
+
const items = values.map(
|
|
738
|
+
(isOptional) => isOptional ? "string | undefined" : "string"
|
|
739
|
+
);
|
|
740
|
+
return `"${name}": [${items.join(", ")}]`;
|
|
741
|
+
});
|
|
742
|
+
return properties.join("; ");
|
|
743
|
+
}
|
|
744
|
+
function parseParams(urlpath) {
|
|
745
|
+
const result = {};
|
|
746
|
+
let segments = urlpath.split("/");
|
|
747
|
+
segments.forEach((segment) => {
|
|
748
|
+
const match = segment.match(/^:([\w-]+)(\?)?/);
|
|
749
|
+
if (!match) return;
|
|
750
|
+
const param = match[1];
|
|
751
|
+
const isOptional = match[2] !== void 0;
|
|
752
|
+
result[param] ??= [];
|
|
753
|
+
result[param].push(isOptional);
|
|
754
|
+
return;
|
|
755
|
+
});
|
|
756
|
+
const hasSplat = segments.at(-1) === "*";
|
|
757
|
+
if (hasSplat) result["*"] = [false];
|
|
758
|
+
return result;
|
|
759
|
+
}
|
|
741
760
|
var import_dedent, Path3, Pathe2, noExtension;
|
|
742
761
|
var init_generate = __esm({
|
|
743
762
|
"typegen/generate.ts"() {
|
|
@@ -798,110 +817,33 @@ async function writeAll(ctx) {
|
|
|
798
817
|
import_node_fs3.default.rmSync(typegenDir, { recursive: true, force: true });
|
|
799
818
|
Object.values(ctx.config.routes).forEach((route) => {
|
|
800
819
|
const typesPath = getTypesPath(ctx, route);
|
|
801
|
-
const content =
|
|
820
|
+
const content = generate(ctx, route);
|
|
802
821
|
import_node_fs3.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
|
|
803
822
|
import_node_fs3.default.writeFileSync(typesPath, content);
|
|
804
823
|
});
|
|
805
|
-
Object.values(ctx.config.routes).map(
|
|
806
|
-
(route) => t2.tsPropertySignature(
|
|
807
|
-
t2.stringLiteral(route.id),
|
|
808
|
-
t2.tsTypeAnnotation(
|
|
809
|
-
t2.tsTypeLiteral([
|
|
810
|
-
t2.tsPropertySignature(
|
|
811
|
-
t2.identifier("parentId"),
|
|
812
|
-
t2.tsTypeAnnotation(
|
|
813
|
-
route.parentId ? t2.tsLiteralType(t2.stringLiteral(route.parentId)) : t2.tsUndefinedKeyword()
|
|
814
|
-
)
|
|
815
|
-
),
|
|
816
|
-
t2.tsPropertySignature(
|
|
817
|
-
t2.identifier("path"),
|
|
818
|
-
t2.tsTypeAnnotation(
|
|
819
|
-
route.path ? t2.tsLiteralType(t2.stringLiteral(route.path)) : t2.tsUndefinedKeyword()
|
|
820
|
-
)
|
|
821
|
-
),
|
|
822
|
-
t2.tsPropertySignature(
|
|
823
|
-
t2.identifier("module"),
|
|
824
|
-
t2.tsTypeAnnotation(
|
|
825
|
-
t2.tsTypeQuery(t2.tsImportType(t2.stringLiteral(route.file)))
|
|
826
|
-
)
|
|
827
|
-
)
|
|
828
|
-
])
|
|
829
|
-
)
|
|
830
|
-
)
|
|
831
|
-
);
|
|
832
|
-
const registerPath = Path4.join(typegenDir, "+register.ts");
|
|
833
|
-
import_node_fs3.default.writeFileSync(registerPath, register(ctx));
|
|
834
|
-
}
|
|
835
|
-
function register(ctx) {
|
|
836
|
-
const routes2 = generate(
|
|
837
|
-
t2.tsTypeAliasDeclaration(
|
|
838
|
-
t2.identifier("Routes"),
|
|
839
|
-
null,
|
|
840
|
-
t2.tsTypeLiteral(
|
|
841
|
-
Object.values(ctx.config.routes).map(
|
|
842
|
-
(route) => t2.tsPropertySignature(
|
|
843
|
-
t2.stringLiteral(route.id),
|
|
844
|
-
t2.tsTypeAnnotation(
|
|
845
|
-
t2.tsTypeLiteral([
|
|
846
|
-
t2.tsPropertySignature(
|
|
847
|
-
t2.identifier("parentId"),
|
|
848
|
-
t2.tsTypeAnnotation(
|
|
849
|
-
route.parentId ? t2.tsLiteralType(t2.stringLiteral(route.parentId)) : t2.tsUndefinedKeyword()
|
|
850
|
-
)
|
|
851
|
-
),
|
|
852
|
-
t2.tsPropertySignature(
|
|
853
|
-
t2.identifier("path"),
|
|
854
|
-
t2.tsTypeAnnotation(
|
|
855
|
-
route.path ? t2.tsLiteralType(t2.stringLiteral(route.path)) : t2.tsUndefinedKeyword()
|
|
856
|
-
)
|
|
857
|
-
),
|
|
858
|
-
t2.tsPropertySignature(
|
|
859
|
-
t2.identifier("module"),
|
|
860
|
-
t2.tsTypeAnnotation(
|
|
861
|
-
t2.tsTypeQuery(
|
|
862
|
-
t2.tsImportType(
|
|
863
|
-
t2.stringLiteral(compiledModulePath(ctx, route))
|
|
864
|
-
)
|
|
865
|
-
)
|
|
866
|
-
)
|
|
867
|
-
)
|
|
868
|
-
])
|
|
869
|
-
)
|
|
870
|
-
)
|
|
871
|
-
)
|
|
872
|
-
)
|
|
873
|
-
)
|
|
874
|
-
).code;
|
|
875
|
-
const registerTypes = import_dedent2.default`
|
|
876
|
-
import "react-router/types";
|
|
877
|
-
|
|
878
|
-
declare module "react-router/types" {
|
|
879
|
-
interface Register {
|
|
880
|
-
routes: Routes;
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
`;
|
|
884
|
-
return [registerTypes, routes2].join("\n\n");
|
|
885
|
-
}
|
|
886
|
-
function compiledModulePath(ctx, route) {
|
|
887
|
-
return "./" + Path4.relative(
|
|
888
|
-
ctx.rootDirectory,
|
|
889
|
-
Path4.join(ctx.config.appDirectory, route.file)
|
|
890
|
-
).replace(/\.(js|ts)x?$/, ".js");
|
|
891
824
|
}
|
|
892
|
-
var import_node_fs3,
|
|
825
|
+
var import_node_fs3, Path4, import_picocolors3;
|
|
893
826
|
var init_typegen = __esm({
|
|
894
827
|
"typegen/index.ts"() {
|
|
895
828
|
"use strict";
|
|
896
829
|
import_node_fs3 = __toESM(require("fs"));
|
|
897
|
-
import_dedent2 = __toESM(require("dedent"));
|
|
898
830
|
Path4 = __toESM(require("pathe"));
|
|
899
831
|
import_picocolors3 = __toESM(require("picocolors"));
|
|
900
832
|
init_config();
|
|
901
|
-
init_babel();
|
|
902
833
|
init_generate();
|
|
903
834
|
init_paths();
|
|
904
|
-
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
// vite/babel.ts
|
|
839
|
+
var import_parser, t, traverse, generate2;
|
|
840
|
+
var init_babel = __esm({
|
|
841
|
+
"vite/babel.ts"() {
|
|
842
|
+
"use strict";
|
|
843
|
+
import_parser = require("@babel/parser");
|
|
844
|
+
t = __toESM(require("@babel/types"));
|
|
845
|
+
traverse = require("@babel/traverse").default;
|
|
846
|
+
generate2 = require("@babel/generator").default;
|
|
905
847
|
}
|
|
906
848
|
});
|
|
907
849
|
|
|
@@ -1028,11 +970,11 @@ var init_route_chunks = __esm({
|
|
|
1028
970
|
});
|
|
1029
971
|
|
|
1030
972
|
// vite/with-props.ts
|
|
1031
|
-
var
|
|
973
|
+
var import_dedent2, vmod;
|
|
1032
974
|
var init_with_props = __esm({
|
|
1033
975
|
"vite/with-props.ts"() {
|
|
1034
976
|
"use strict";
|
|
1035
|
-
|
|
977
|
+
import_dedent2 = __toESM(require("dedent"));
|
|
1036
978
|
init_babel();
|
|
1037
979
|
init_virtual_module();
|
|
1038
980
|
vmod = create("with-props");
|
|
@@ -1635,8 +1577,8 @@ var babel = __toESM(require("@babel/core"));
|
|
|
1635
1577
|
var import_plugin_syntax_jsx = __toESM(require("@babel/plugin-syntax-jsx"));
|
|
1636
1578
|
var import_preset_typescript = __toESM(require("@babel/preset-typescript"));
|
|
1637
1579
|
var import_prettier = __toESM(require("prettier"));
|
|
1638
|
-
function transpile(
|
|
1639
|
-
let mjs = babel.transformSync(
|
|
1580
|
+
function transpile(tsx, options = {}) {
|
|
1581
|
+
let mjs = babel.transformSync(tsx, {
|
|
1640
1582
|
compact: false,
|
|
1641
1583
|
cwd: options.cwd,
|
|
1642
1584
|
filename: options.filename,
|
|
@@ -1760,8 +1702,8 @@ async function checkForEntry(rootDirectory, appDirectory, entries2) {
|
|
|
1760
1702
|
let entryPath = path9.resolve(appDirectory, entry);
|
|
1761
1703
|
let exists = await import_fs_extra2.default.pathExists(entryPath);
|
|
1762
1704
|
if (exists) {
|
|
1763
|
-
let
|
|
1764
|
-
console.error(import_picocolors7.default.red(`Entry file ${
|
|
1705
|
+
let relative8 = path9.relative(rootDirectory, entryPath);
|
|
1706
|
+
console.error(import_picocolors7.default.red(`Entry file ${relative8} already exists.`));
|
|
1765
1707
|
return process.exit(1);
|
|
1766
1708
|
}
|
|
1767
1709
|
}
|
package/dist/config.js
CHANGED
package/dist/routes.js
CHANGED
|
@@ -53,7 +53,7 @@ const enqueueUpdate = debounce(async () => {
|
|
|
53
53
|
needsRevalidation,
|
|
54
54
|
manifest.routes,
|
|
55
55
|
window.__reactRouterRouteModules,
|
|
56
|
-
window.__reactRouterContext.
|
|
56
|
+
window.__reactRouterContext.ssr,
|
|
57
57
|
window.__reactRouterContext.isSpaMode
|
|
58
58
|
);
|
|
59
59
|
__reactRouterDataRouter._internalSetRoutes(routes);
|
package/dist/vite/cloudflare.js
CHANGED
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-902325fda
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -59,7 +59,6 @@ var import_kebabCase = __toESM(require("lodash/kebabCase"));
|
|
|
59
59
|
|
|
60
60
|
// typegen/index.ts
|
|
61
61
|
var import_node_fs2 = __toESM(require("fs"));
|
|
62
|
-
var import_dedent2 = __toESM(require("dedent"));
|
|
63
62
|
var Path4 = __toESM(require("pathe"));
|
|
64
63
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
65
64
|
|
|
@@ -633,19 +632,6 @@ function findEntry(dir, basename2, options) {
|
|
|
633
632
|
return void 0;
|
|
634
633
|
}
|
|
635
634
|
|
|
636
|
-
// vite/babel.ts
|
|
637
|
-
var babel_exports = {};
|
|
638
|
-
__export(babel_exports, {
|
|
639
|
-
generate: () => generate,
|
|
640
|
-
parse: () => import_parser.parse,
|
|
641
|
-
t: () => t,
|
|
642
|
-
traverse: () => traverse
|
|
643
|
-
});
|
|
644
|
-
var import_parser = require("@babel/parser");
|
|
645
|
-
var t = __toESM(require("@babel/types"));
|
|
646
|
-
var traverse = require("@babel/traverse").default;
|
|
647
|
-
var generate = require("@babel/generator").default;
|
|
648
|
-
|
|
649
635
|
// typegen/generate.ts
|
|
650
636
|
var import_dedent = __toESM(require("dedent"));
|
|
651
637
|
var Path3 = __toESM(require("pathe"));
|
|
@@ -667,8 +653,9 @@ function getTypesPath(ctx, route) {
|
|
|
667
653
|
}
|
|
668
654
|
|
|
669
655
|
// typegen/generate.ts
|
|
670
|
-
function
|
|
656
|
+
function generate(ctx, route) {
|
|
671
657
|
const lineage = getRouteLineage(ctx.config.routes, route);
|
|
658
|
+
const urlpath = lineage.map((route2) => route2.path).join("/");
|
|
672
659
|
const typesPath = getTypesPath(ctx, route);
|
|
673
660
|
const parents = lineage.slice(0, -1);
|
|
674
661
|
const parentTypeImports = parents.map((parent, i) => {
|
|
@@ -686,15 +673,22 @@ function generate2(ctx, route) {
|
|
|
686
673
|
// ${route.file}
|
|
687
674
|
|
|
688
675
|
import type * as T from "react-router/route-module"
|
|
689
|
-
import type { Routes } from "react-router/types"
|
|
690
676
|
|
|
691
677
|
${parentTypeImports}
|
|
692
678
|
|
|
693
|
-
type
|
|
679
|
+
type Module = typeof import("../${Pathe2.filename(route.file)}.js")
|
|
694
680
|
|
|
695
|
-
export type Info =
|
|
681
|
+
export type Info = {
|
|
696
682
|
parents: [${parents.map((_, i) => `Parent${i}`).join(", ")}],
|
|
697
|
-
id:
|
|
683
|
+
id: "${route.id}"
|
|
684
|
+
file: "${route.file}"
|
|
685
|
+
path: "${route.path}"
|
|
686
|
+
params: {${formatParamProperties(
|
|
687
|
+
urlpath
|
|
688
|
+
)}} & { [key: string]: string | undefined }
|
|
689
|
+
module: Module
|
|
690
|
+
loaderData: T.CreateLoaderData<Module>
|
|
691
|
+
actionData: T.CreateActionData<Module>
|
|
698
692
|
}
|
|
699
693
|
|
|
700
694
|
export namespace Route {
|
|
@@ -730,9 +724,38 @@ function getRouteLineage(routes, route) {
|
|
|
730
724
|
result.reverse();
|
|
731
725
|
return result;
|
|
732
726
|
}
|
|
727
|
+
function formatParamProperties(urlpath) {
|
|
728
|
+
const params = parseParams(urlpath);
|
|
729
|
+
const properties = Object.entries(params).map(([name, values]) => {
|
|
730
|
+
if (values.length === 1) {
|
|
731
|
+
const isOptional = values[0];
|
|
732
|
+
return isOptional ? `"${name}"?: string` : `"${name}": string`;
|
|
733
|
+
}
|
|
734
|
+
const items = values.map(
|
|
735
|
+
(isOptional) => isOptional ? "string | undefined" : "string"
|
|
736
|
+
);
|
|
737
|
+
return `"${name}": [${items.join(", ")}]`;
|
|
738
|
+
});
|
|
739
|
+
return properties.join("; ");
|
|
740
|
+
}
|
|
741
|
+
function parseParams(urlpath) {
|
|
742
|
+
const result = {};
|
|
743
|
+
let segments = urlpath.split("/");
|
|
744
|
+
segments.forEach((segment) => {
|
|
745
|
+
const match = segment.match(/^:([\w-]+)(\?)?/);
|
|
746
|
+
if (!match) return;
|
|
747
|
+
const param = match[1];
|
|
748
|
+
const isOptional = match[2] !== void 0;
|
|
749
|
+
result[param] ??= [];
|
|
750
|
+
result[param].push(isOptional);
|
|
751
|
+
return;
|
|
752
|
+
});
|
|
753
|
+
const hasSplat = segments.at(-1) === "*";
|
|
754
|
+
if (hasSplat) result["*"] = [false];
|
|
755
|
+
return result;
|
|
756
|
+
}
|
|
733
757
|
|
|
734
758
|
// typegen/index.ts
|
|
735
|
-
var { t: t2 } = babel_exports;
|
|
736
759
|
async function watch(rootDirectory, { logger } = {}) {
|
|
737
760
|
const ctx = await createContext2({ rootDirectory, watch: true });
|
|
738
761
|
await writeAll(ctx);
|
|
@@ -776,98 +799,18 @@ async function writeAll(ctx) {
|
|
|
776
799
|
import_node_fs2.default.rmSync(typegenDir, { recursive: true, force: true });
|
|
777
800
|
Object.values(ctx.config.routes).forEach((route) => {
|
|
778
801
|
const typesPath = getTypesPath(ctx, route);
|
|
779
|
-
const content =
|
|
802
|
+
const content = generate(ctx, route);
|
|
780
803
|
import_node_fs2.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
|
|
781
804
|
import_node_fs2.default.writeFileSync(typesPath, content);
|
|
782
805
|
});
|
|
783
|
-
Object.values(ctx.config.routes).map(
|
|
784
|
-
(route) => t2.tsPropertySignature(
|
|
785
|
-
t2.stringLiteral(route.id),
|
|
786
|
-
t2.tsTypeAnnotation(
|
|
787
|
-
t2.tsTypeLiteral([
|
|
788
|
-
t2.tsPropertySignature(
|
|
789
|
-
t2.identifier("parentId"),
|
|
790
|
-
t2.tsTypeAnnotation(
|
|
791
|
-
route.parentId ? t2.tsLiteralType(t2.stringLiteral(route.parentId)) : t2.tsUndefinedKeyword()
|
|
792
|
-
)
|
|
793
|
-
),
|
|
794
|
-
t2.tsPropertySignature(
|
|
795
|
-
t2.identifier("path"),
|
|
796
|
-
t2.tsTypeAnnotation(
|
|
797
|
-
route.path ? t2.tsLiteralType(t2.stringLiteral(route.path)) : t2.tsUndefinedKeyword()
|
|
798
|
-
)
|
|
799
|
-
),
|
|
800
|
-
t2.tsPropertySignature(
|
|
801
|
-
t2.identifier("module"),
|
|
802
|
-
t2.tsTypeAnnotation(
|
|
803
|
-
t2.tsTypeQuery(t2.tsImportType(t2.stringLiteral(route.file)))
|
|
804
|
-
)
|
|
805
|
-
)
|
|
806
|
-
])
|
|
807
|
-
)
|
|
808
|
-
)
|
|
809
|
-
);
|
|
810
|
-
const registerPath = Path4.join(typegenDir, "+register.ts");
|
|
811
|
-
import_node_fs2.default.writeFileSync(registerPath, register(ctx));
|
|
812
|
-
}
|
|
813
|
-
function register(ctx) {
|
|
814
|
-
const routes = generate(
|
|
815
|
-
t2.tsTypeAliasDeclaration(
|
|
816
|
-
t2.identifier("Routes"),
|
|
817
|
-
null,
|
|
818
|
-
t2.tsTypeLiteral(
|
|
819
|
-
Object.values(ctx.config.routes).map(
|
|
820
|
-
(route) => t2.tsPropertySignature(
|
|
821
|
-
t2.stringLiteral(route.id),
|
|
822
|
-
t2.tsTypeAnnotation(
|
|
823
|
-
t2.tsTypeLiteral([
|
|
824
|
-
t2.tsPropertySignature(
|
|
825
|
-
t2.identifier("parentId"),
|
|
826
|
-
t2.tsTypeAnnotation(
|
|
827
|
-
route.parentId ? t2.tsLiteralType(t2.stringLiteral(route.parentId)) : t2.tsUndefinedKeyword()
|
|
828
|
-
)
|
|
829
|
-
),
|
|
830
|
-
t2.tsPropertySignature(
|
|
831
|
-
t2.identifier("path"),
|
|
832
|
-
t2.tsTypeAnnotation(
|
|
833
|
-
route.path ? t2.tsLiteralType(t2.stringLiteral(route.path)) : t2.tsUndefinedKeyword()
|
|
834
|
-
)
|
|
835
|
-
),
|
|
836
|
-
t2.tsPropertySignature(
|
|
837
|
-
t2.identifier("module"),
|
|
838
|
-
t2.tsTypeAnnotation(
|
|
839
|
-
t2.tsTypeQuery(
|
|
840
|
-
t2.tsImportType(
|
|
841
|
-
t2.stringLiteral(compiledModulePath(ctx, route))
|
|
842
|
-
)
|
|
843
|
-
)
|
|
844
|
-
)
|
|
845
|
-
)
|
|
846
|
-
])
|
|
847
|
-
)
|
|
848
|
-
)
|
|
849
|
-
)
|
|
850
|
-
)
|
|
851
|
-
)
|
|
852
|
-
).code;
|
|
853
|
-
const registerTypes = import_dedent2.default`
|
|
854
|
-
import "react-router/types";
|
|
855
|
-
|
|
856
|
-
declare module "react-router/types" {
|
|
857
|
-
interface Register {
|
|
858
|
-
routes: Routes;
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
`;
|
|
862
|
-
return [registerTypes, routes].join("\n\n");
|
|
863
|
-
}
|
|
864
|
-
function compiledModulePath(ctx, route) {
|
|
865
|
-
return "./" + Path4.relative(
|
|
866
|
-
ctx.rootDirectory,
|
|
867
|
-
Path4.join(ctx.config.appDirectory, route.file)
|
|
868
|
-
).replace(/\.(js|ts)x?$/, ".js");
|
|
869
806
|
}
|
|
870
807
|
|
|
808
|
+
// vite/babel.ts
|
|
809
|
+
var import_parser = require("@babel/parser");
|
|
810
|
+
var t = __toESM(require("@babel/types"));
|
|
811
|
+
var traverse = require("@babel/traverse").default;
|
|
812
|
+
var generate2 = require("@babel/generator").default;
|
|
813
|
+
|
|
871
814
|
// vite/node-adapter.ts
|
|
872
815
|
var import_node_events = require("events");
|
|
873
816
|
var import_node_stream = require("stream");
|
|
@@ -1654,7 +1597,7 @@ function getChunkedExport(code, exportName, generateOptions = {}, cache, cacheKe
|
|
|
1654
1597
|
}
|
|
1655
1598
|
throw new Error(`Unknown export node type: ${node.type}`);
|
|
1656
1599
|
}).filter((node) => node !== null);
|
|
1657
|
-
return
|
|
1600
|
+
return generate2(ast, generateOptions);
|
|
1658
1601
|
}
|
|
1659
1602
|
);
|
|
1660
1603
|
}
|
|
@@ -1770,7 +1713,7 @@ function omitChunkedExports(code, exportNames, generateOptions = {}, cache, cach
|
|
|
1770
1713
|
if (ast.program.body.length === 0) {
|
|
1771
1714
|
return void 0;
|
|
1772
1715
|
}
|
|
1773
|
-
return
|
|
1716
|
+
return generate2(ast, generateOptions);
|
|
1774
1717
|
}
|
|
1775
1718
|
);
|
|
1776
1719
|
}
|
|
@@ -1832,7 +1775,7 @@ function getRouteChunkNameFromModuleId(id) {
|
|
|
1832
1775
|
}
|
|
1833
1776
|
|
|
1834
1777
|
// vite/with-props.ts
|
|
1835
|
-
var
|
|
1778
|
+
var import_dedent2 = __toESM(require("dedent"));
|
|
1836
1779
|
var vmod = create("with-props");
|
|
1837
1780
|
var NAMED_COMPONENT_EXPORTS = ["HydrateFallback", "ErrorBoundary"];
|
|
1838
1781
|
var plugin = {
|
|
@@ -1843,7 +1786,7 @@ var plugin = {
|
|
|
1843
1786
|
},
|
|
1844
1787
|
async load(id) {
|
|
1845
1788
|
if (id !== vmod.resolvedId) return;
|
|
1846
|
-
return
|
|
1789
|
+
return import_dedent2.default`
|
|
1847
1790
|
import { createElement as h } from "react";
|
|
1848
1791
|
import { useActionData, useLoaderData, useMatches, useParams, useRouteError } from "react-router";
|
|
1849
1792
|
|
|
@@ -1863,6 +1806,8 @@ var plugin = {
|
|
|
1863
1806
|
return function Wrapped() {
|
|
1864
1807
|
const props = {
|
|
1865
1808
|
params: useParams(),
|
|
1809
|
+
loaderData: useLoaderData(),
|
|
1810
|
+
actionData: useActionData(),
|
|
1866
1811
|
};
|
|
1867
1812
|
return h(HydrateFallback, props);
|
|
1868
1813
|
};
|
|
@@ -2223,6 +2168,11 @@ var reactRouterVitePlugin = () => {
|
|
|
2223
2168
|
// Otherwise, all routes are imported as usual
|
|
2224
2169
|
ctx.reactRouterConfig.routes
|
|
2225
2170
|
);
|
|
2171
|
+
let prerenderPaths = await getPrerenderPaths(
|
|
2172
|
+
ctx.reactRouterConfig.prerender,
|
|
2173
|
+
ctx.reactRouterConfig.ssr,
|
|
2174
|
+
routes
|
|
2175
|
+
);
|
|
2226
2176
|
return `
|
|
2227
2177
|
import * as entryServer from ${JSON.stringify(
|
|
2228
2178
|
resolveFileUrl(ctx, ctx.entryServerFilePath)
|
|
@@ -2249,6 +2199,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2249
2199
|
export const future = ${JSON.stringify(ctx.reactRouterConfig.future)};
|
|
2250
2200
|
export const ssr = ${ctx.reactRouterConfig.ssr};
|
|
2251
2201
|
export const isSpaMode = ${isSpaModeEnabled(ctx.reactRouterConfig)};
|
|
2202
|
+
export const prerender = ${JSON.stringify(prerenderPaths)};
|
|
2252
2203
|
export const publicPath = ${JSON.stringify(ctx.publicPath)};
|
|
2253
2204
|
export const entry = { module: entryServer };
|
|
2254
2205
|
export const routes = {
|
|
@@ -2775,7 +2726,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2775
2726
|
].join("\n")
|
|
2776
2727
|
);
|
|
2777
2728
|
}
|
|
2778
|
-
if (ctx.reactRouterConfig
|
|
2729
|
+
if (isPrerenderingEnabled(ctx.reactRouterConfig)) {
|
|
2779
2730
|
await handlePrerender(
|
|
2780
2731
|
viteConfig,
|
|
2781
2732
|
ctx.reactRouterConfig,
|
|
@@ -3049,12 +3000,15 @@ var reactRouterVitePlugin = () => {
|
|
|
3049
3000
|
if (!route) return;
|
|
3050
3001
|
if (!options?.ssr && isSpaModeEnabled(ctx.reactRouterConfig)) {
|
|
3051
3002
|
let exportNames = getExportNames(code);
|
|
3052
|
-
let serverOnlyExports = exportNames.filter(
|
|
3053
|
-
(exp
|
|
3054
|
-
|
|
3003
|
+
let serverOnlyExports = exportNames.filter((exp) => {
|
|
3004
|
+
if (route.id === "root" && exp === "loader") {
|
|
3005
|
+
return false;
|
|
3006
|
+
}
|
|
3007
|
+
return SERVER_ONLY_ROUTE_EXPORTS.includes(exp);
|
|
3008
|
+
});
|
|
3055
3009
|
if (serverOnlyExports.length > 0) {
|
|
3056
3010
|
let str = serverOnlyExports.map((e) => `\`${e}\``).join(", ");
|
|
3057
|
-
let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://
|
|
3011
|
+
let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://reactrouter.com/how-to/spa for more information.`;
|
|
3058
3012
|
throw Error(message);
|
|
3059
3013
|
}
|
|
3060
3014
|
if (route.id !== "root") {
|
|
@@ -3062,7 +3016,7 @@ var reactRouterVitePlugin = () => {
|
|
|
3062
3016
|
(exp) => exp === "HydrateFallback"
|
|
3063
3017
|
);
|
|
3064
3018
|
if (hasHydrateFallback) {
|
|
3065
|
-
let message = `SPA Mode: Invalid \`HydrateFallback\` export found in \`${route.file}\`. \`HydrateFallback\` is only permitted on the root route in SPA Mode. See https://
|
|
3019
|
+
let message = `SPA Mode: Invalid \`HydrateFallback\` export found in \`${route.file}\`. \`HydrateFallback\` is only permitted on the root route in SPA Mode. See https://reactrouter.com/how-to/spa for more information.`;
|
|
3066
3020
|
throw Error(message);
|
|
3067
3021
|
}
|
|
3068
3022
|
}
|
|
@@ -3073,7 +3027,7 @@ var reactRouterVitePlugin = () => {
|
|
|
3073
3027
|
removeExports(ast, SERVER_ONLY_ROUTE_EXPORTS);
|
|
3074
3028
|
}
|
|
3075
3029
|
transform(ast);
|
|
3076
|
-
return
|
|
3030
|
+
return generate2(ast, {
|
|
3077
3031
|
sourceMaps: true,
|
|
3078
3032
|
filename: id,
|
|
3079
3033
|
sourceFileName: filepath
|
|
@@ -3355,8 +3309,11 @@ async function getRouteMetadata(cache, ctx, viteChildCompiler, route, readRouteF
|
|
|
3355
3309
|
};
|
|
3356
3310
|
return info;
|
|
3357
3311
|
}
|
|
3312
|
+
function isPrerenderingEnabled(reactRouterConfig) {
|
|
3313
|
+
return reactRouterConfig.prerender != null && reactRouterConfig.prerender !== false;
|
|
3314
|
+
}
|
|
3358
3315
|
function isSpaModeEnabled(reactRouterConfig) {
|
|
3359
|
-
return reactRouterConfig.ssr === false && (reactRouterConfig
|
|
3316
|
+
return reactRouterConfig.ssr === false && !isPrerenderingEnabled(reactRouterConfig);
|
|
3360
3317
|
}
|
|
3361
3318
|
async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, serverBuildFile) {
|
|
3362
3319
|
let serverBuildPath = path6.join(serverBuildDirectory, serverBuildFile);
|
|
@@ -3368,20 +3325,49 @@ async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, ser
|
|
|
3368
3325
|
};
|
|
3369
3326
|
}
|
|
3370
3327
|
async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildFile, clientBuildDirectory) {
|
|
3371
|
-
let { handler } = await getPrerenderBuildAndHandler(
|
|
3328
|
+
let { build, handler } = await getPrerenderBuildAndHandler(
|
|
3372
3329
|
viteConfig,
|
|
3373
3330
|
serverBuildDirectory,
|
|
3374
3331
|
serverBuildFile
|
|
3375
3332
|
);
|
|
3376
|
-
let request = new Request(`http://localhost${reactRouterConfig.basename}
|
|
3333
|
+
let request = new Request(`http://localhost${reactRouterConfig.basename}`, {
|
|
3334
|
+
headers: {
|
|
3335
|
+
// Enable SPA mode in the server runtime and only render down to the root
|
|
3336
|
+
"X-React-Router-SPA-Mode": "yes"
|
|
3337
|
+
}
|
|
3338
|
+
});
|
|
3377
3339
|
let response = await handler(request);
|
|
3378
3340
|
let html = await response.text();
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3341
|
+
let isPrerenderSpaFallback = build.prerender.includes("/");
|
|
3342
|
+
let filename3 = isPrerenderSpaFallback ? "__spa-fallback.html" : "index.html";
|
|
3343
|
+
if (response.status !== 200) {
|
|
3344
|
+
if (isPrerenderSpaFallback) {
|
|
3345
|
+
throw new Error(
|
|
3346
|
+
`Prerender: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename3}\` file.
|
|
3347
|
+
` + html
|
|
3348
|
+
);
|
|
3349
|
+
} else {
|
|
3350
|
+
throw new Error(
|
|
3351
|
+
`SPA Mode: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename3}\` file.
|
|
3352
|
+
` + html
|
|
3353
|
+
);
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
if (!html.includes("window.__reactRouterContext =") || !html.includes("window.__reactRouterRouteModules =")) {
|
|
3357
|
+
throw new Error(
|
|
3358
|
+
"SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`."
|
|
3359
|
+
);
|
|
3360
|
+
}
|
|
3361
|
+
await fse.writeFile(path6.join(clientBuildDirectory, filename3), html);
|
|
3362
|
+
let prettyDir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3363
|
+
let prettyPath = path6.join(prettyDir, filename3);
|
|
3364
|
+
if (build.prerender.length > 0) {
|
|
3365
|
+
viteConfig.logger.info(
|
|
3366
|
+
`Prerender (html): SPA Fallback -> ${import_picocolors3.default.bold(prettyPath)}`
|
|
3367
|
+
);
|
|
3368
|
+
} else {
|
|
3369
|
+
viteConfig.logger.info(`SPA Mode: Generated ${import_picocolors3.default.bold(prettyPath)}`);
|
|
3370
|
+
}
|
|
3385
3371
|
}
|
|
3386
3372
|
async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildPath, clientBuildDirectory) {
|
|
3387
3373
|
let { build, handler } = await getPrerenderBuildAndHandler(
|
|
@@ -3390,29 +3376,22 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
|
|
|
3390
3376
|
serverBuildPath
|
|
3391
3377
|
);
|
|
3392
3378
|
let routes = createPrerenderRoutes(build.routes);
|
|
3393
|
-
let
|
|
3394
|
-
if (typeof reactRouterConfig.prerender === "boolean") {
|
|
3395
|
-
invariant(reactRouterConfig.prerender, "Expected prerender:true");
|
|
3396
|
-
routesToPrerender = determineStaticPrerenderRoutes(
|
|
3397
|
-
routes,
|
|
3398
|
-
viteConfig,
|
|
3399
|
-
true
|
|
3400
|
-
);
|
|
3401
|
-
} else if (typeof reactRouterConfig.prerender === "function") {
|
|
3402
|
-
routesToPrerender = await reactRouterConfig.prerender({
|
|
3403
|
-
getStaticPaths: () => determineStaticPrerenderRoutes(routes, viteConfig, false)
|
|
3404
|
-
});
|
|
3405
|
-
} else {
|
|
3406
|
-
routesToPrerender = reactRouterConfig.prerender || ["/"];
|
|
3407
|
-
}
|
|
3379
|
+
let prerenderedRoutes = /* @__PURE__ */ new Set();
|
|
3408
3380
|
let headers = {
|
|
3409
3381
|
// Header that can be used in the loader to know if you're running at
|
|
3410
3382
|
// build time or runtime
|
|
3411
3383
|
"X-React-Router-Prerender": "yes"
|
|
3412
3384
|
};
|
|
3413
|
-
for (let path7 of
|
|
3385
|
+
for (let path7 of build.prerender) {
|
|
3414
3386
|
let matches = (0, import_react_router2.matchRoutes)(routes, `/${path7}/`.replace(/^\/\/+/, "/"));
|
|
3415
|
-
|
|
3387
|
+
invariant(
|
|
3388
|
+
matches,
|
|
3389
|
+
`Unable to prerender path because it does not match any routes: ${path7}`
|
|
3390
|
+
);
|
|
3391
|
+
matches.forEach((m) => prerenderedRoutes.add(m.route.id));
|
|
3392
|
+
let hasLoaders = matches.some(
|
|
3393
|
+
(m) => build.assets.routes[m.route.id]?.hasLoader
|
|
3394
|
+
);
|
|
3416
3395
|
let data;
|
|
3417
3396
|
if (hasLoaders) {
|
|
3418
3397
|
data = await prerenderData(
|
|
@@ -3452,8 +3431,34 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
|
|
|
3452
3431
|
);
|
|
3453
3432
|
}
|
|
3454
3433
|
}
|
|
3434
|
+
if (reactRouterConfig.ssr === false) {
|
|
3435
|
+
let errors = [];
|
|
3436
|
+
for (let [routeId, route] of Object.entries(build.routes)) {
|
|
3437
|
+
let invalidApis = [];
|
|
3438
|
+
if (route) {
|
|
3439
|
+
if (route.module.headers) invalidApis.push("headers");
|
|
3440
|
+
if (route.module.action) invalidApis.push("action");
|
|
3441
|
+
if (invalidApis.length > 0) {
|
|
3442
|
+
errors.push(
|
|
3443
|
+
`Prerender: ${invalidApis.length} invalid route export(s) in \`${route.id}\` when prerendering with \`ssr:false\`: ${invalidApis.join(", ")}. See https://reactrouter.com/how-to/spa for more information.`
|
|
3444
|
+
);
|
|
3445
|
+
}
|
|
3446
|
+
if (route.module.loader && !prerenderedRoutes.has(routeId)) {
|
|
3447
|
+
errors.push(
|
|
3448
|
+
`Prerender: 1 invalid route export in \`${route.id}\` when using \`ssr:false\` with \`prerender\` because the route is never prerendered so the loader will never be called. See https://reactrouter.com/how-to/spa for more information.`
|
|
3449
|
+
);
|
|
3450
|
+
}
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
if (errors.length > 0) {
|
|
3454
|
+
viteConfig.logger.error(errors.join("\n"));
|
|
3455
|
+
throw new Error(
|
|
3456
|
+
"Invalid route exports found when prerendering with `ssr:false`"
|
|
3457
|
+
);
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3455
3460
|
}
|
|
3456
|
-
function
|
|
3461
|
+
function getStaticPrerenderPaths(routes) {
|
|
3457
3462
|
let paths = ["/"];
|
|
3458
3463
|
let paramRoutes = [];
|
|
3459
3464
|
function recurse(subtree, prefix = "") {
|
|
@@ -3473,28 +3478,29 @@ function determineStaticPrerenderRoutes(routes, viteConfig, isBooleanUsage = fal
|
|
|
3473
3478
|
}
|
|
3474
3479
|
}
|
|
3475
3480
|
recurse(routes);
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
"You may want to use the `prerender()` API to prerender the following paths:",
|
|
3481
|
-
...paramRoutes.map((p) => " - " + p)
|
|
3482
|
-
].join("\n")
|
|
3483
|
-
);
|
|
3484
|
-
}
|
|
3485
|
-
return paths.map((p) => p.replace(/\/\/+/g, "/").replace(/(.+)\/$/, "$1"));
|
|
3481
|
+
return {
|
|
3482
|
+
paths: paths.map((p) => p.replace(/\/\/+/g, "/").replace(/(.+)\/$/, "$1")),
|
|
3483
|
+
paramRoutes
|
|
3484
|
+
};
|
|
3486
3485
|
}
|
|
3487
3486
|
async function prerenderData(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
3488
3487
|
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath === "/" ? "/_root.data" : `${prerenderPath.replace(/\/$/, "")}.data`}`.replace(/\/\/+/g, "/");
|
|
3489
3488
|
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
3490
3489
|
let response = await handler(request);
|
|
3491
3490
|
let data = await response.text();
|
|
3492
|
-
|
|
3491
|
+
if (response.status !== 200) {
|
|
3492
|
+
throw new Error(
|
|
3493
|
+
`Prerender (data): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${path6}\` path.
|
|
3494
|
+
${normalizedPath}`
|
|
3495
|
+
);
|
|
3496
|
+
}
|
|
3493
3497
|
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3494
3498
|
let outfile = path6.join(outdir, ...normalizedPath.split("/"));
|
|
3495
3499
|
await fse.ensureDir(path6.dirname(outfile));
|
|
3496
3500
|
await fse.outputFile(outfile, data);
|
|
3497
|
-
viteConfig.logger.info(
|
|
3501
|
+
viteConfig.logger.info(
|
|
3502
|
+
`Prerender (data): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
3503
|
+
);
|
|
3498
3504
|
return data;
|
|
3499
3505
|
}
|
|
3500
3506
|
async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
@@ -3505,42 +3511,65 @@ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reac
|
|
|
3505
3511
|
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
3506
3512
|
let response = await handler(request);
|
|
3507
3513
|
let html = await response.text();
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3514
|
+
if (response.status !== 200) {
|
|
3515
|
+
throw new Error(
|
|
3516
|
+
`Prerender (html): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.
|
|
3517
|
+
${html}`
|
|
3518
|
+
);
|
|
3511
3519
|
}
|
|
3512
3520
|
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3513
3521
|
let outfile = path6.join(outdir, ...normalizedPath.split("/"), "index.html");
|
|
3514
3522
|
await fse.ensureDir(path6.dirname(outfile));
|
|
3515
3523
|
await fse.outputFile(outfile, html);
|
|
3516
|
-
viteConfig.logger.info(
|
|
3524
|
+
viteConfig.logger.info(
|
|
3525
|
+
`Prerender (html): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
3526
|
+
);
|
|
3517
3527
|
}
|
|
3518
3528
|
async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
3519
3529
|
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
|
|
3520
3530
|
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
3521
3531
|
let response = await handler(request);
|
|
3522
3532
|
let text = await response.text();
|
|
3523
|
-
validatePrerenderedResponse(response, text, "Prerender", normalizedPath);
|
|
3524
|
-
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3525
|
-
let outfile = path6.join(outdir, ...normalizedPath.split("/"));
|
|
3526
|
-
await fse.ensureDir(path6.dirname(outfile));
|
|
3527
|
-
await fse.outputFile(outfile, text);
|
|
3528
|
-
viteConfig.logger.info(`Prerender: Generated ${import_picocolors3.default.bold(outfile)}`);
|
|
3529
|
-
}
|
|
3530
|
-
function validatePrerenderedResponse(response, html, prefix, path7) {
|
|
3531
3533
|
if (response.status !== 200) {
|
|
3532
3534
|
throw new Error(
|
|
3533
|
-
|
|
3534
|
-
${
|
|
3535
|
+
`Prerender (resource): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.
|
|
3536
|
+
${text}`
|
|
3535
3537
|
);
|
|
3536
3538
|
}
|
|
3539
|
+
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3540
|
+
let outfile = path6.join(outdir, ...normalizedPath.split("/"));
|
|
3541
|
+
await fse.ensureDir(path6.dirname(outfile));
|
|
3542
|
+
await fse.outputFile(outfile, text);
|
|
3543
|
+
viteConfig.logger.info(
|
|
3544
|
+
`Prerender (resource): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
3545
|
+
);
|
|
3537
3546
|
}
|
|
3538
|
-
function
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
)
|
|
3547
|
+
async function getPrerenderPaths(prerender, ssr, routes) {
|
|
3548
|
+
let prerenderPaths = [];
|
|
3549
|
+
if (prerender != null && prerender !== false) {
|
|
3550
|
+
let prerenderRoutes = createPrerenderRoutes(routes);
|
|
3551
|
+
if (prerender === true) {
|
|
3552
|
+
let { paths, paramRoutes } = getStaticPrerenderPaths(prerenderRoutes);
|
|
3553
|
+
if (!ssr && paramRoutes.length > 0) {
|
|
3554
|
+
console.warn(
|
|
3555
|
+
import_picocolors3.default.yellow(
|
|
3556
|
+
[
|
|
3557
|
+
"\u26A0\uFE0F Paths with dynamic/splat params cannot be prerendered when using `prerender: true`. You may want to use the `prerender()` API to prerender the following paths:",
|
|
3558
|
+
...paramRoutes.map((p) => " - " + p)
|
|
3559
|
+
].join("\n")
|
|
3560
|
+
)
|
|
3561
|
+
);
|
|
3562
|
+
}
|
|
3563
|
+
prerenderPaths = paths;
|
|
3564
|
+
} else if (typeof prerender === "function") {
|
|
3565
|
+
prerenderPaths = await prerender({
|
|
3566
|
+
getStaticPaths: () => getStaticPrerenderPaths(prerenderRoutes).paths
|
|
3567
|
+
});
|
|
3568
|
+
} else {
|
|
3569
|
+
prerenderPaths = prerender || ["/"];
|
|
3570
|
+
}
|
|
3543
3571
|
}
|
|
3572
|
+
return prerenderPaths;
|
|
3544
3573
|
}
|
|
3545
3574
|
function groupRoutesByParentId2(manifest) {
|
|
3546
3575
|
let routes = {};
|
|
@@ -3558,19 +3587,16 @@ function groupRoutesByParentId2(manifest) {
|
|
|
3558
3587
|
function createPrerenderRoutes(manifest, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) {
|
|
3559
3588
|
return (routesByParentId[parentId] || []).map((route) => {
|
|
3560
3589
|
let commonRoute = {
|
|
3561
|
-
// Always include root due to default boundaries
|
|
3562
|
-
hasErrorBoundary: route.id === "root" || route.module.ErrorBoundary != null,
|
|
3563
3590
|
id: route.id,
|
|
3564
|
-
path: route.path
|
|
3565
|
-
loader: route.module.loader ? () => null : void 0,
|
|
3566
|
-
action: void 0,
|
|
3567
|
-
handle: route.module.handle
|
|
3591
|
+
path: route.path
|
|
3568
3592
|
};
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3593
|
+
if (route.index) {
|
|
3594
|
+
return {
|
|
3595
|
+
index: true,
|
|
3596
|
+
...commonRoute
|
|
3597
|
+
};
|
|
3598
|
+
}
|
|
3599
|
+
return {
|
|
3574
3600
|
children: createPrerenderRoutes(manifest, route.id, routesByParentId),
|
|
3575
3601
|
...commonRoute
|
|
3576
3602
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-router/dev",
|
|
3
|
-
"version": "0.0.0-experimental-
|
|
3
|
+
"version": "0.0.0-experimental-902325fda",
|
|
4
4
|
"description": "Dev tools and CLI for React Router",
|
|
5
5
|
"homepage": "https://reactrouter.com",
|
|
6
6
|
"bugs": {
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"set-cookie-parser": "^2.6.0",
|
|
89
89
|
"valibot": "^0.41.0",
|
|
90
90
|
"vite-node": "3.0.0-beta.2",
|
|
91
|
-
"@react-router/node": "0.0.0-experimental-
|
|
91
|
+
"@react-router/node": "0.0.0-experimental-902325fda"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@types/babel__core": "^7.20.5",
|
|
@@ -117,15 +117,15 @@
|
|
|
117
117
|
"vite": "^6.0.0",
|
|
118
118
|
"wireit": "0.14.9",
|
|
119
119
|
"wrangler": "^3.28.2",
|
|
120
|
-
"react-router": "
|
|
121
|
-
"
|
|
120
|
+
"@react-router/serve": "0.0.0-experimental-902325fda",
|
|
121
|
+
"react-router": "^0.0.0-experimental-902325fda"
|
|
122
122
|
},
|
|
123
123
|
"peerDependencies": {
|
|
124
124
|
"typescript": "^5.1.0",
|
|
125
125
|
"vite": "^5.1.0 || ^6.0.0",
|
|
126
126
|
"wrangler": "^3.28.2",
|
|
127
|
-
"@react-router/serve": "^0.0.0-experimental-
|
|
128
|
-
"react-router": "^0.0.0-experimental-
|
|
127
|
+
"@react-router/serve": "^0.0.0-experimental-902325fda",
|
|
128
|
+
"react-router": "^0.0.0-experimental-902325fda"
|
|
129
129
|
},
|
|
130
130
|
"peerDependenciesMeta": {
|
|
131
131
|
"@react-router/serve": {
|