@react-router/dev 0.0.0-experimental-902325fda → 0.0.0-experimental-208f173a8
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 +368 -164
- package/dist/config.d.ts +4 -0
- package/dist/config.js +1 -1
- package/dist/routes.js +1 -1
- package/dist/static/refresh-utils.cjs +1 -1
- package/dist/vite/cloudflare.js +487 -3
- package/dist/vite.js +375 -263
- package/package.json +6 -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-208f173a8
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -59,6 +59,7 @@ 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"));
|
|
62
63
|
var Path4 = __toESM(require("pathe"));
|
|
63
64
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
64
65
|
|
|
@@ -453,7 +454,8 @@ async function resolveConfig({
|
|
|
453
454
|
}
|
|
454
455
|
let future = {
|
|
455
456
|
unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
|
|
456
|
-
unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false
|
|
457
|
+
unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false,
|
|
458
|
+
unstable_viteEnvironmentApi: reactRouterUserConfig.future?.unstable_viteEnvironmentApi ?? false
|
|
457
459
|
};
|
|
458
460
|
let reactRouterConfig = deepFreeze({
|
|
459
461
|
appDirectory,
|
|
@@ -632,6 +634,19 @@ function findEntry(dir, basename2, options) {
|
|
|
632
634
|
return void 0;
|
|
633
635
|
}
|
|
634
636
|
|
|
637
|
+
// vite/babel.ts
|
|
638
|
+
var babel_exports = {};
|
|
639
|
+
__export(babel_exports, {
|
|
640
|
+
generate: () => generate,
|
|
641
|
+
parse: () => import_parser.parse,
|
|
642
|
+
t: () => t,
|
|
643
|
+
traverse: () => traverse
|
|
644
|
+
});
|
|
645
|
+
var import_parser = require("@babel/parser");
|
|
646
|
+
var t = __toESM(require("@babel/types"));
|
|
647
|
+
var traverse = require("@babel/traverse").default;
|
|
648
|
+
var generate = require("@babel/generator").default;
|
|
649
|
+
|
|
635
650
|
// typegen/generate.ts
|
|
636
651
|
var import_dedent = __toESM(require("dedent"));
|
|
637
652
|
var Path3 = __toESM(require("pathe"));
|
|
@@ -653,7 +668,7 @@ function getTypesPath(ctx, route) {
|
|
|
653
668
|
}
|
|
654
669
|
|
|
655
670
|
// typegen/generate.ts
|
|
656
|
-
function
|
|
671
|
+
function generate2(ctx, route) {
|
|
657
672
|
const lineage = getRouteLineage(ctx.config.routes, route);
|
|
658
673
|
const urlpath = lineage.map((route2) => route2.path).join("/");
|
|
659
674
|
const typesPath = getTypesPath(ctx, route);
|
|
@@ -799,17 +814,78 @@ async function writeAll(ctx) {
|
|
|
799
814
|
import_node_fs2.default.rmSync(typegenDir, { recursive: true, force: true });
|
|
800
815
|
Object.values(ctx.config.routes).forEach((route) => {
|
|
801
816
|
const typesPath = getTypesPath(ctx, route);
|
|
802
|
-
const content =
|
|
817
|
+
const content = generate2(ctx, route);
|
|
803
818
|
import_node_fs2.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
|
|
804
819
|
import_node_fs2.default.writeFileSync(typesPath, content);
|
|
805
820
|
});
|
|
821
|
+
const registerPath = Path4.join(typegenDir, "+register.ts");
|
|
822
|
+
import_node_fs2.default.writeFileSync(registerPath, register(ctx));
|
|
806
823
|
}
|
|
824
|
+
function register(ctx) {
|
|
825
|
+
const register2 = import_dedent2.default`
|
|
826
|
+
import "react-router";
|
|
807
827
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
828
|
+
declare module "react-router" {
|
|
829
|
+
interface Register {
|
|
830
|
+
params: Params;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
`;
|
|
834
|
+
const { t: t2 } = babel_exports;
|
|
835
|
+
const typeParams = t2.tsTypeAliasDeclaration(
|
|
836
|
+
t2.identifier("Params"),
|
|
837
|
+
null,
|
|
838
|
+
t2.tsTypeLiteral(
|
|
839
|
+
Object.values(ctx.config.routes).map((route) => {
|
|
840
|
+
if (route.id !== "root" && !route.path) return void 0;
|
|
841
|
+
const lineage = getRouteLineage2(ctx.config.routes, route);
|
|
842
|
+
const fullpath = route.id === "root" ? "/" : lineage.map((route2) => route2.path).filter((path7) => path7 !== void 0).join("/");
|
|
843
|
+
const params = parseParams2(fullpath);
|
|
844
|
+
return t2.tsPropertySignature(
|
|
845
|
+
t2.stringLiteral(fullpath),
|
|
846
|
+
t2.tsTypeAnnotation(
|
|
847
|
+
t2.tsTypeLiteral(
|
|
848
|
+
Object.entries(params).map(([param, isRequired]) => {
|
|
849
|
+
const property = t2.tsPropertySignature(
|
|
850
|
+
t2.stringLiteral(param),
|
|
851
|
+
t2.tsTypeAnnotation(t2.tsStringKeyword())
|
|
852
|
+
);
|
|
853
|
+
property.optional = !isRequired;
|
|
854
|
+
return property;
|
|
855
|
+
})
|
|
856
|
+
)
|
|
857
|
+
)
|
|
858
|
+
);
|
|
859
|
+
}).filter((x) => x !== void 0)
|
|
860
|
+
)
|
|
861
|
+
);
|
|
862
|
+
return [register2, generate(typeParams).code].join("\n\n");
|
|
863
|
+
}
|
|
864
|
+
function parseParams2(fullpath) {
|
|
865
|
+
const result = {};
|
|
866
|
+
let segments = fullpath.split("/");
|
|
867
|
+
segments.forEach((segment) => {
|
|
868
|
+
const match = segment.match(/^:([\w-]+)(\?)?/);
|
|
869
|
+
if (!match) return;
|
|
870
|
+
const param = match[1];
|
|
871
|
+
const isRequired = match[2] === void 0;
|
|
872
|
+
result[param] ||= isRequired;
|
|
873
|
+
return;
|
|
874
|
+
});
|
|
875
|
+
const hasSplat = segments.at(-1) === "*";
|
|
876
|
+
if (hasSplat) result["*"] = true;
|
|
877
|
+
return result;
|
|
878
|
+
}
|
|
879
|
+
function getRouteLineage2(routes, route) {
|
|
880
|
+
const result = [];
|
|
881
|
+
while (route) {
|
|
882
|
+
result.push(route);
|
|
883
|
+
if (!route.parentId) break;
|
|
884
|
+
route = routes[route.parentId];
|
|
885
|
+
}
|
|
886
|
+
result.reverse();
|
|
887
|
+
return result;
|
|
888
|
+
}
|
|
813
889
|
|
|
814
890
|
// vite/node-adapter.ts
|
|
815
891
|
var import_node_events = require("events");
|
|
@@ -1597,7 +1673,7 @@ function getChunkedExport(code, exportName, generateOptions = {}, cache, cacheKe
|
|
|
1597
1673
|
}
|
|
1598
1674
|
throw new Error(`Unknown export node type: ${node.type}`);
|
|
1599
1675
|
}).filter((node) => node !== null);
|
|
1600
|
-
return
|
|
1676
|
+
return generate(ast, generateOptions);
|
|
1601
1677
|
}
|
|
1602
1678
|
);
|
|
1603
1679
|
}
|
|
@@ -1713,7 +1789,7 @@ function omitChunkedExports(code, exportNames, generateOptions = {}, cache, cach
|
|
|
1713
1789
|
if (ast.program.body.length === 0) {
|
|
1714
1790
|
return void 0;
|
|
1715
1791
|
}
|
|
1716
|
-
return
|
|
1792
|
+
return generate(ast, generateOptions);
|
|
1717
1793
|
}
|
|
1718
1794
|
);
|
|
1719
1795
|
}
|
|
@@ -1775,7 +1851,7 @@ function getRouteChunkNameFromModuleId(id) {
|
|
|
1775
1851
|
}
|
|
1776
1852
|
|
|
1777
1853
|
// vite/with-props.ts
|
|
1778
|
-
var
|
|
1854
|
+
var import_dedent3 = __toESM(require("dedent"));
|
|
1779
1855
|
var vmod = create("with-props");
|
|
1780
1856
|
var NAMED_COMPONENT_EXPORTS = ["HydrateFallback", "ErrorBoundary"];
|
|
1781
1857
|
var plugin = {
|
|
@@ -1786,7 +1862,7 @@ var plugin = {
|
|
|
1786
1862
|
},
|
|
1787
1863
|
async load(id) {
|
|
1788
1864
|
if (id !== vmod.resolvedId) return;
|
|
1789
|
-
return
|
|
1865
|
+
return import_dedent3.default`
|
|
1790
1866
|
import { createElement as h } from "react";
|
|
1791
1867
|
import { useActionData, useLoaderData, useMatches, useParams, useRouteError } from "react-router";
|
|
1792
1868
|
|
|
@@ -1806,8 +1882,6 @@ var plugin = {
|
|
|
1806
1882
|
return function Wrapped() {
|
|
1807
1883
|
const props = {
|
|
1808
1884
|
params: useParams(),
|
|
1809
|
-
loaderData: useLoaderData(),
|
|
1810
|
-
actionData: useActionData(),
|
|
1811
1885
|
};
|
|
1812
1886
|
return h(HydrateFallback, props);
|
|
1813
1887
|
};
|
|
@@ -1915,6 +1989,20 @@ var CLIENT_ROUTE_EXPORTS = [
|
|
|
1915
1989
|
"shouldRevalidate"
|
|
1916
1990
|
];
|
|
1917
1991
|
var BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
|
|
1992
|
+
var SSR_BUNDLE_PREFIX = "ssrBundle_";
|
|
1993
|
+
function isSeverBundleEnvironmentName(name) {
|
|
1994
|
+
return name.startsWith(SSR_BUNDLE_PREFIX);
|
|
1995
|
+
}
|
|
1996
|
+
function getServerEnvironmentEntries(record, buildManifest) {
|
|
1997
|
+
return Object.entries(record).filter(
|
|
1998
|
+
([name]) => buildManifest.serverBundles ? isSeverBundleEnvironmentName(name) : name === "ssr"
|
|
1999
|
+
);
|
|
2000
|
+
}
|
|
2001
|
+
function getServerEnvironmentValues(record, buildManifest) {
|
|
2002
|
+
return getServerEnvironmentEntries(record, buildManifest).map(
|
|
2003
|
+
([, value]) => value
|
|
2004
|
+
);
|
|
2005
|
+
}
|
|
1918
2006
|
var isRouteEntryModuleId = (id) => {
|
|
1919
2007
|
return id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING);
|
|
1920
2008
|
};
|
|
@@ -2083,7 +2171,7 @@ var resolveEnvironmentBuildContext = ({
|
|
|
2083
2171
|
let buildContext = viteUserConfig.__reactRouterEnvironmentBuildContext;
|
|
2084
2172
|
let resolvedBuildContext = {
|
|
2085
2173
|
name: buildContext.name,
|
|
2086
|
-
options: buildContext.resolveOptions({
|
|
2174
|
+
options: buildContext.resolveOptions({ viteUserConfig })
|
|
2087
2175
|
};
|
|
2088
2176
|
return resolvedBuildContext;
|
|
2089
2177
|
};
|
|
@@ -2108,6 +2196,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2108
2196
|
let viteUserConfig;
|
|
2109
2197
|
let viteConfigEnv;
|
|
2110
2198
|
let viteConfig;
|
|
2199
|
+
let buildManifest;
|
|
2111
2200
|
let cssModulesManifest = {};
|
|
2112
2201
|
let viteChildCompiler = null;
|
|
2113
2202
|
let cache = /* @__PURE__ */ new Map();
|
|
@@ -2168,11 +2257,6 @@ var reactRouterVitePlugin = () => {
|
|
|
2168
2257
|
// Otherwise, all routes are imported as usual
|
|
2169
2258
|
ctx.reactRouterConfig.routes
|
|
2170
2259
|
);
|
|
2171
|
-
let prerenderPaths = await getPrerenderPaths(
|
|
2172
|
-
ctx.reactRouterConfig.prerender,
|
|
2173
|
-
ctx.reactRouterConfig.ssr,
|
|
2174
|
-
routes
|
|
2175
|
-
);
|
|
2176
2260
|
return `
|
|
2177
2261
|
import * as entryServer from ${JSON.stringify(
|
|
2178
2262
|
resolveFileUrl(ctx, ctx.entryServerFilePath)
|
|
@@ -2199,7 +2283,6 @@ var reactRouterVitePlugin = () => {
|
|
|
2199
2283
|
export const future = ${JSON.stringify(ctx.reactRouterConfig.future)};
|
|
2200
2284
|
export const ssr = ${ctx.reactRouterConfig.ssr};
|
|
2201
2285
|
export const isSpaMode = ${isSpaModeEnabled(ctx.reactRouterConfig)};
|
|
2202
|
-
export const prerender = ${JSON.stringify(prerenderPaths)};
|
|
2203
2286
|
export const publicPath = ${JSON.stringify(ctx.publicPath)};
|
|
2204
2287
|
export const entry = { module: entryServer };
|
|
2205
2288
|
export const routes = {
|
|
@@ -2432,14 +2515,6 @@ var reactRouterVitePlugin = () => {
|
|
|
2432
2515
|
let viteClientConditions = [
|
|
2433
2516
|
...vite2.defaultClientConditions ?? []
|
|
2434
2517
|
];
|
|
2435
|
-
let packageRoot = path6.dirname(
|
|
2436
|
-
require.resolve("@react-router/dev/package.json")
|
|
2437
|
-
);
|
|
2438
|
-
let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
|
|
2439
|
-
let viteServerConditions = [
|
|
2440
|
-
...vite2.defaultServerConditions ?? [],
|
|
2441
|
-
...moduleSyncEnabled ? ["module-sync"] : []
|
|
2442
|
-
];
|
|
2443
2518
|
logger = vite2.createLogger(viteUserConfig.logLevel, {
|
|
2444
2519
|
prefix: "[react-router]"
|
|
2445
2520
|
});
|
|
@@ -2455,26 +2530,37 @@ var reactRouterVitePlugin = () => {
|
|
|
2455
2530
|
watch: viteCommand === "serve"
|
|
2456
2531
|
});
|
|
2457
2532
|
await updatePluginContext();
|
|
2533
|
+
buildManifest = await getBuildManifest(ctx);
|
|
2458
2534
|
Object.assign(
|
|
2459
2535
|
process.env,
|
|
2460
2536
|
vite2.loadEnv(
|
|
2461
2537
|
viteConfigEnv.mode,
|
|
2462
|
-
ctx.rootDirectory,
|
|
2538
|
+
viteUserConfig.envDir ?? ctx.rootDirectory,
|
|
2463
2539
|
// We override default prefix of "VITE_" with a blank string since
|
|
2464
2540
|
// we're targeting the server, so we want to load all environment
|
|
2465
2541
|
// variables, not just those explicitly marked for the client
|
|
2466
2542
|
""
|
|
2467
2543
|
)
|
|
2468
2544
|
);
|
|
2545
|
+
let environments = await getEnvironmentsOptions(
|
|
2546
|
+
ctx,
|
|
2547
|
+
buildManifest,
|
|
2548
|
+
viteCommand,
|
|
2549
|
+
{ viteUserConfig }
|
|
2550
|
+
);
|
|
2551
|
+
let serverEnvironment = getServerEnvironmentValues(
|
|
2552
|
+
environments,
|
|
2553
|
+
buildManifest
|
|
2554
|
+
)[0];
|
|
2555
|
+
invariant(serverEnvironment);
|
|
2556
|
+
let clientEnvironment = environments.client;
|
|
2557
|
+
invariant(clientEnvironment);
|
|
2469
2558
|
return {
|
|
2470
2559
|
__reactRouterPluginContext: ctx,
|
|
2471
2560
|
appType: viteCommand === "serve" && viteConfigEnv.mode === "production" && ctx.reactRouterConfig.ssr === false ? "spa" : "custom",
|
|
2472
2561
|
ssr: {
|
|
2473
|
-
external:
|
|
2474
|
-
resolve:
|
|
2475
|
-
conditions: viteCommand === "build" ? viteServerConditions : ["development", ...viteServerConditions],
|
|
2476
|
-
externalConditions: viteCommand === "build" ? viteServerConditions : ["development", ...viteServerConditions]
|
|
2477
|
-
}
|
|
2562
|
+
external: serverEnvironment.resolve?.external,
|
|
2563
|
+
resolve: serverEnvironment.resolve
|
|
2478
2564
|
},
|
|
2479
2565
|
optimizeDeps: {
|
|
2480
2566
|
entries: ctx.reactRouterConfig.future.unstable_optimizeDeps ? [
|
|
@@ -2523,11 +2609,41 @@ var reactRouterVitePlugin = () => {
|
|
|
2523
2609
|
// will throw an error that the file is not allowed to be read.
|
|
2524
2610
|
// https://vitejs.dev/config/server-options#server-fs-allow
|
|
2525
2611
|
server: viteUserConfig.server?.fs?.allow ? { fs: { allow: defaultEntries } } : void 0,
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2612
|
+
...ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? {
|
|
2613
|
+
environments,
|
|
2614
|
+
build: {
|
|
2615
|
+
// This isn't honored by the SSR environment config (which seems
|
|
2616
|
+
// to be a Vite bug?) so we set it here too.
|
|
2617
|
+
ssrEmitAssets: true
|
|
2618
|
+
},
|
|
2619
|
+
builder: {
|
|
2620
|
+
sharedConfigBuild: true,
|
|
2621
|
+
sharedPlugins: true,
|
|
2622
|
+
async buildApp(builder) {
|
|
2623
|
+
invariant(viteConfig);
|
|
2624
|
+
invariant(buildManifest);
|
|
2625
|
+
viteConfig.logger.info(
|
|
2626
|
+
"Using Vite Environment API (experimental)"
|
|
2627
|
+
);
|
|
2628
|
+
let { reactRouterConfig } = ctx;
|
|
2629
|
+
await cleanBuildDirectory(viteConfig, ctx);
|
|
2630
|
+
await builder.build(builder.environments.client);
|
|
2631
|
+
let serverEnvironments = getServerEnvironmentValues(
|
|
2632
|
+
builder.environments,
|
|
2633
|
+
buildManifest
|
|
2634
|
+
);
|
|
2635
|
+
await Promise.all(serverEnvironments.map(builder.build));
|
|
2636
|
+
await cleanViteManifests(environments, ctx);
|
|
2637
|
+
await reactRouterConfig.buildEnd?.({
|
|
2638
|
+
buildManifest,
|
|
2639
|
+
reactRouterConfig,
|
|
2640
|
+
viteConfig
|
|
2641
|
+
});
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
} : {
|
|
2645
|
+
build: ctx.environmentBuildContext?.options.build ?? (viteConfigEnv.isSsrBuild ? serverEnvironment.build : clientEnvironment.build)
|
|
2646
|
+
}
|
|
2531
2647
|
};
|
|
2532
2648
|
},
|
|
2533
2649
|
async configResolved(resolvedViteConfig) {
|
|
@@ -2685,14 +2801,15 @@ var reactRouterVitePlugin = () => {
|
|
|
2685
2801
|
// After the SSR build is finished, we inspect the Vite manifest for
|
|
2686
2802
|
// the SSR build and move server-only assets to client assets directory
|
|
2687
2803
|
async handler() {
|
|
2688
|
-
|
|
2804
|
+
let { future } = ctx.reactRouterConfig;
|
|
2805
|
+
if (future.unstable_viteEnvironmentApi ? this.environment.name === "client" : !viteConfigEnv.isSsrBuild) {
|
|
2689
2806
|
return;
|
|
2690
2807
|
}
|
|
2691
2808
|
invariant(viteConfig);
|
|
2692
2809
|
let clientBuildDirectory = getClientBuildDirectory(
|
|
2693
2810
|
ctx.reactRouterConfig
|
|
2694
2811
|
);
|
|
2695
|
-
let serverBuildDirectory = ctx.environmentBuildContext?.options.build
|
|
2812
|
+
let serverBuildDirectory = future.unstable_viteEnvironmentApi ? this.environment.config?.build?.outDir : ctx.environmentBuildContext?.options.build?.outDir ?? getServerBuildDirectory(ctx);
|
|
2696
2813
|
let ssrViteManifest = await loadViteManifest(serverBuildDirectory);
|
|
2697
2814
|
let ssrAssetPaths = getViteManifestAssetPaths(ssrViteManifest);
|
|
2698
2815
|
let movedAssetPaths = [];
|
|
@@ -2726,7 +2843,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2726
2843
|
].join("\n")
|
|
2727
2844
|
);
|
|
2728
2845
|
}
|
|
2729
|
-
if (
|
|
2846
|
+
if (ctx.reactRouterConfig.prerender != null && ctx.reactRouterConfig.prerender !== false) {
|
|
2730
2847
|
await handlePrerender(
|
|
2731
2848
|
viteConfig,
|
|
2732
2849
|
ctx.reactRouterConfig,
|
|
@@ -3000,15 +3117,12 @@ var reactRouterVitePlugin = () => {
|
|
|
3000
3117
|
if (!route) return;
|
|
3001
3118
|
if (!options?.ssr && isSpaModeEnabled(ctx.reactRouterConfig)) {
|
|
3002
3119
|
let exportNames = getExportNames(code);
|
|
3003
|
-
let serverOnlyExports = exportNames.filter(
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
}
|
|
3007
|
-
return SERVER_ONLY_ROUTE_EXPORTS.includes(exp);
|
|
3008
|
-
});
|
|
3120
|
+
let serverOnlyExports = exportNames.filter(
|
|
3121
|
+
(exp) => SERVER_ONLY_ROUTE_EXPORTS.includes(exp)
|
|
3122
|
+
);
|
|
3009
3123
|
if (serverOnlyExports.length > 0) {
|
|
3010
3124
|
let str = serverOnlyExports.map((e) => `\`${e}\``).join(", ");
|
|
3011
|
-
let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://
|
|
3125
|
+
let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://remix.run/guides/spa-mode for more information.`;
|
|
3012
3126
|
throw Error(message);
|
|
3013
3127
|
}
|
|
3014
3128
|
if (route.id !== "root") {
|
|
@@ -3016,7 +3130,7 @@ var reactRouterVitePlugin = () => {
|
|
|
3016
3130
|
(exp) => exp === "HydrateFallback"
|
|
3017
3131
|
);
|
|
3018
3132
|
if (hasHydrateFallback) {
|
|
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://
|
|
3133
|
+
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.`;
|
|
3020
3134
|
throw Error(message);
|
|
3021
3135
|
}
|
|
3022
3136
|
}
|
|
@@ -3027,7 +3141,7 @@ var reactRouterVitePlugin = () => {
|
|
|
3027
3141
|
removeExports(ast, SERVER_ONLY_ROUTE_EXPORTS);
|
|
3028
3142
|
}
|
|
3029
3143
|
transform(ast);
|
|
3030
|
-
return
|
|
3144
|
+
return generate(ast, {
|
|
3031
3145
|
sourceMaps: true,
|
|
3032
3146
|
filename: id,
|
|
3033
3147
|
sourceFileName: filepath
|
|
@@ -3309,11 +3423,8 @@ async function getRouteMetadata(cache, ctx, viteChildCompiler, route, readRouteF
|
|
|
3309
3423
|
};
|
|
3310
3424
|
return info;
|
|
3311
3425
|
}
|
|
3312
|
-
function isPrerenderingEnabled(reactRouterConfig) {
|
|
3313
|
-
return reactRouterConfig.prerender != null && reactRouterConfig.prerender !== false;
|
|
3314
|
-
}
|
|
3315
3426
|
function isSpaModeEnabled(reactRouterConfig) {
|
|
3316
|
-
return reactRouterConfig.ssr === false &&
|
|
3427
|
+
return reactRouterConfig.ssr === false && (reactRouterConfig.prerender == null || reactRouterConfig.prerender === false || Array.isArray(reactRouterConfig.prerender) && reactRouterConfig.prerender.length === 1 && reactRouterConfig.prerender[0] === "/");
|
|
3317
3428
|
}
|
|
3318
3429
|
async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, serverBuildFile) {
|
|
3319
3430
|
let serverBuildPath = path6.join(serverBuildDirectory, serverBuildFile);
|
|
@@ -3325,49 +3436,20 @@ async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, ser
|
|
|
3325
3436
|
};
|
|
3326
3437
|
}
|
|
3327
3438
|
async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildFile, clientBuildDirectory) {
|
|
3328
|
-
let {
|
|
3439
|
+
let { handler } = await getPrerenderBuildAndHandler(
|
|
3329
3440
|
viteConfig,
|
|
3330
3441
|
serverBuildDirectory,
|
|
3331
3442
|
serverBuildFile
|
|
3332
3443
|
);
|
|
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
|
-
});
|
|
3444
|
+
let request = new Request(`http://localhost${reactRouterConfig.basename}`);
|
|
3339
3445
|
let response = await handler(request);
|
|
3340
3446
|
let html = await response.text();
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
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
|
-
}
|
|
3447
|
+
validatePrerenderedResponse(response, html, "SPA Mode", "/");
|
|
3448
|
+
validatePrerenderedHtml(html, "SPA Mode");
|
|
3449
|
+
await fse.writeFile(path6.join(clientBuildDirectory, "index.html"), html);
|
|
3450
|
+
viteConfig.logger.info(
|
|
3451
|
+
"SPA Mode: index.html has been written to your " + import_picocolors3.default.bold(path6.relative(process.cwd(), clientBuildDirectory)) + " directory"
|
|
3452
|
+
);
|
|
3371
3453
|
}
|
|
3372
3454
|
async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildPath, clientBuildDirectory) {
|
|
3373
3455
|
let { build, handler } = await getPrerenderBuildAndHandler(
|
|
@@ -3376,22 +3458,29 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
|
|
|
3376
3458
|
serverBuildPath
|
|
3377
3459
|
);
|
|
3378
3460
|
let routes = createPrerenderRoutes(build.routes);
|
|
3379
|
-
let
|
|
3461
|
+
let routesToPrerender;
|
|
3462
|
+
if (typeof reactRouterConfig.prerender === "boolean") {
|
|
3463
|
+
invariant(reactRouterConfig.prerender, "Expected prerender:true");
|
|
3464
|
+
routesToPrerender = determineStaticPrerenderRoutes(
|
|
3465
|
+
routes,
|
|
3466
|
+
viteConfig,
|
|
3467
|
+
true
|
|
3468
|
+
);
|
|
3469
|
+
} else if (typeof reactRouterConfig.prerender === "function") {
|
|
3470
|
+
routesToPrerender = await reactRouterConfig.prerender({
|
|
3471
|
+
getStaticPaths: () => determineStaticPrerenderRoutes(routes, viteConfig, false)
|
|
3472
|
+
});
|
|
3473
|
+
} else {
|
|
3474
|
+
routesToPrerender = reactRouterConfig.prerender || ["/"];
|
|
3475
|
+
}
|
|
3380
3476
|
let headers = {
|
|
3381
3477
|
// Header that can be used in the loader to know if you're running at
|
|
3382
3478
|
// build time or runtime
|
|
3383
3479
|
"X-React-Router-Prerender": "yes"
|
|
3384
3480
|
};
|
|
3385
|
-
for (let path7 of
|
|
3481
|
+
for (let path7 of routesToPrerender) {
|
|
3386
3482
|
let matches = (0, import_react_router2.matchRoutes)(routes, `/${path7}/`.replace(/^\/\/+/, "/"));
|
|
3387
|
-
|
|
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
|
-
);
|
|
3483
|
+
let hasLoaders = matches?.some((m) => m.route.loader);
|
|
3395
3484
|
let data;
|
|
3396
3485
|
if (hasLoaders) {
|
|
3397
3486
|
data = await prerenderData(
|
|
@@ -3431,34 +3520,8 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
|
|
|
3431
3520
|
);
|
|
3432
3521
|
}
|
|
3433
3522
|
}
|
|
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
|
-
}
|
|
3460
3523
|
}
|
|
3461
|
-
function
|
|
3524
|
+
function determineStaticPrerenderRoutes(routes, viteConfig, isBooleanUsage = false) {
|
|
3462
3525
|
let paths = ["/"];
|
|
3463
3526
|
let paramRoutes = [];
|
|
3464
3527
|
function recurse(subtree, prefix = "") {
|
|
@@ -3478,29 +3541,28 @@ function getStaticPrerenderPaths(routes) {
|
|
|
3478
3541
|
}
|
|
3479
3542
|
}
|
|
3480
3543
|
recurse(routes);
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3544
|
+
if (isBooleanUsage && paramRoutes.length > 0) {
|
|
3545
|
+
viteConfig.logger.warn(
|
|
3546
|
+
[
|
|
3547
|
+
"\u26A0\uFE0F Paths with dynamic/splat params cannot be prerendered when using `prerender: true`.",
|
|
3548
|
+
"You may want to use the `prerender()` API to prerender the following paths:",
|
|
3549
|
+
...paramRoutes.map((p) => " - " + p)
|
|
3550
|
+
].join("\n")
|
|
3551
|
+
);
|
|
3552
|
+
}
|
|
3553
|
+
return paths.map((p) => p.replace(/\/\/+/g, "/").replace(/(.+)\/$/, "$1"));
|
|
3485
3554
|
}
|
|
3486
3555
|
async function prerenderData(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
3487
3556
|
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath === "/" ? "/_root.data" : `${prerenderPath.replace(/\/$/, "")}.data`}`.replace(/\/\/+/g, "/");
|
|
3488
3557
|
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
3489
3558
|
let response = await handler(request);
|
|
3490
3559
|
let data = await response.text();
|
|
3491
|
-
|
|
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
|
-
}
|
|
3560
|
+
validatePrerenderedResponse(response, data, "Prerender", normalizedPath);
|
|
3497
3561
|
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3498
3562
|
let outfile = path6.join(outdir, ...normalizedPath.split("/"));
|
|
3499
3563
|
await fse.ensureDir(path6.dirname(outfile));
|
|
3500
3564
|
await fse.outputFile(outfile, data);
|
|
3501
|
-
viteConfig.logger.info(
|
|
3502
|
-
`Prerender (data): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
3503
|
-
);
|
|
3565
|
+
viteConfig.logger.info(`Prerender: Generated ${import_picocolors3.default.bold(outfile)}`);
|
|
3504
3566
|
return data;
|
|
3505
3567
|
}
|
|
3506
3568
|
async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
@@ -3511,65 +3573,42 @@ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reac
|
|
|
3511
3573
|
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
3512
3574
|
let response = await handler(request);
|
|
3513
3575
|
let html = await response.text();
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
${html}`
|
|
3518
|
-
);
|
|
3576
|
+
validatePrerenderedResponse(response, html, "Prerender", normalizedPath);
|
|
3577
|
+
if (!reactRouterConfig.ssr) {
|
|
3578
|
+
validatePrerenderedHtml(html, "Prerender");
|
|
3519
3579
|
}
|
|
3520
3580
|
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3521
3581
|
let outfile = path6.join(outdir, ...normalizedPath.split("/"), "index.html");
|
|
3522
3582
|
await fse.ensureDir(path6.dirname(outfile));
|
|
3523
3583
|
await fse.outputFile(outfile, html);
|
|
3524
|
-
viteConfig.logger.info(
|
|
3525
|
-
`Prerender (html): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
3526
|
-
);
|
|
3584
|
+
viteConfig.logger.info(`Prerender: Generated ${import_picocolors3.default.bold(outfile)}`);
|
|
3527
3585
|
}
|
|
3528
3586
|
async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
3529
3587
|
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
|
|
3530
3588
|
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
3531
3589
|
let response = await handler(request);
|
|
3532
3590
|
let text = await response.text();
|
|
3533
|
-
|
|
3534
|
-
throw new Error(
|
|
3535
|
-
`Prerender (resource): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.
|
|
3536
|
-
${text}`
|
|
3537
|
-
);
|
|
3538
|
-
}
|
|
3591
|
+
validatePrerenderedResponse(response, text, "Prerender", normalizedPath);
|
|
3539
3592
|
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3540
3593
|
let outfile = path6.join(outdir, ...normalizedPath.split("/"));
|
|
3541
3594
|
await fse.ensureDir(path6.dirname(outfile));
|
|
3542
3595
|
await fse.outputFile(outfile, text);
|
|
3543
|
-
viteConfig.logger.info(
|
|
3544
|
-
`Prerender (resource): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
3545
|
-
);
|
|
3596
|
+
viteConfig.logger.info(`Prerender: Generated ${import_picocolors3.default.bold(outfile)}`);
|
|
3546
3597
|
}
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
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
|
-
}
|
|
3598
|
+
function validatePrerenderedResponse(response, html, prefix, path7) {
|
|
3599
|
+
if (response.status !== 200) {
|
|
3600
|
+
throw new Error(
|
|
3601
|
+
`${prefix}: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${path7}\` path.
|
|
3602
|
+
${html}`
|
|
3603
|
+
);
|
|
3604
|
+
}
|
|
3605
|
+
}
|
|
3606
|
+
function validatePrerenderedHtml(html, prefix) {
|
|
3607
|
+
if (!html.includes("window.__reactRouterContext =") || !html.includes("window.__reactRouterRouteModules =")) {
|
|
3608
|
+
throw new Error(
|
|
3609
|
+
`${prefix}: Did you forget to include <Scripts/> in your root route? Your pre-rendered HTML files cannot hydrate without \`<Scripts />\`.`
|
|
3610
|
+
);
|
|
3571
3611
|
}
|
|
3572
|
-
return prerenderPaths;
|
|
3573
3612
|
}
|
|
3574
3613
|
function groupRoutesByParentId2(manifest) {
|
|
3575
3614
|
let routes = {};
|
|
@@ -3587,16 +3626,19 @@ function groupRoutesByParentId2(manifest) {
|
|
|
3587
3626
|
function createPrerenderRoutes(manifest, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) {
|
|
3588
3627
|
return (routesByParentId[parentId] || []).map((route) => {
|
|
3589
3628
|
let commonRoute = {
|
|
3629
|
+
// Always include root due to default boundaries
|
|
3630
|
+
hasErrorBoundary: route.id === "root" || route.module.ErrorBoundary != null,
|
|
3590
3631
|
id: route.id,
|
|
3591
|
-
path: route.path
|
|
3632
|
+
path: route.path,
|
|
3633
|
+
loader: route.module.loader ? () => null : void 0,
|
|
3634
|
+
action: void 0,
|
|
3635
|
+
handle: route.module.handle
|
|
3592
3636
|
};
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
}
|
|
3599
|
-
return {
|
|
3637
|
+
return route.index ? {
|
|
3638
|
+
index: true,
|
|
3639
|
+
...commonRoute
|
|
3640
|
+
} : {
|
|
3641
|
+
caseSensitive: route.caseSensitive,
|
|
3600
3642
|
children: createPrerenderRoutes(manifest, route.id, routesByParentId),
|
|
3601
3643
|
...commonRoute
|
|
3602
3644
|
};
|
|
@@ -3715,6 +3757,39 @@ function validateRouteChunks({
|
|
|
3715
3757
|
].join("\n\n")
|
|
3716
3758
|
);
|
|
3717
3759
|
}
|
|
3760
|
+
async function cleanBuildDirectory(viteConfig, ctx) {
|
|
3761
|
+
let buildDirectory = ctx.reactRouterConfig.buildDirectory;
|
|
3762
|
+
let isWithinRoot = () => {
|
|
3763
|
+
let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
|
|
3764
|
+
return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
|
|
3765
|
+
};
|
|
3766
|
+
if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
|
|
3767
|
+
await fse.remove(buildDirectory);
|
|
3768
|
+
}
|
|
3769
|
+
}
|
|
3770
|
+
async function cleanViteManifests(environmentsOptions, ctx) {
|
|
3771
|
+
let viteManifestPaths = Object.entries(environmentsOptions).map(
|
|
3772
|
+
([environmentName, options]) => {
|
|
3773
|
+
let outDir = options.build?.outDir;
|
|
3774
|
+
invariant(outDir, `Expected build.outDir for ${environmentName}`);
|
|
3775
|
+
return path6.join(outDir, ".vite/manifest.json");
|
|
3776
|
+
}
|
|
3777
|
+
);
|
|
3778
|
+
await Promise.all(
|
|
3779
|
+
viteManifestPaths.map(async (viteManifestPath) => {
|
|
3780
|
+
let manifestExists = await fse.pathExists(viteManifestPath);
|
|
3781
|
+
if (!manifestExists) return;
|
|
3782
|
+
if (!ctx.viteManifestEnabled) {
|
|
3783
|
+
await fse.remove(viteManifestPath);
|
|
3784
|
+
}
|
|
3785
|
+
let viteDir = path6.dirname(viteManifestPath);
|
|
3786
|
+
let viteDirFiles = await fse.readdir(viteDir);
|
|
3787
|
+
if (viteDirFiles.length === 0) {
|
|
3788
|
+
await fse.remove(viteDir);
|
|
3789
|
+
}
|
|
3790
|
+
})
|
|
3791
|
+
);
|
|
3792
|
+
}
|
|
3718
3793
|
async function getBuildManifest(ctx) {
|
|
3719
3794
|
let { routes, serverBundles, appDirectory } = ctx.reactRouterConfig;
|
|
3720
3795
|
if (!serverBundles) {
|
|
@@ -3774,77 +3849,101 @@ async function getBuildManifest(ctx) {
|
|
|
3774
3849
|
);
|
|
3775
3850
|
return buildManifest;
|
|
3776
3851
|
}
|
|
3777
|
-
function
|
|
3852
|
+
function mergeEnvironmentOptions(base, ...overrides) {
|
|
3778
3853
|
let vite2 = getVite();
|
|
3779
|
-
return
|
|
3854
|
+
return overrides.reduce(
|
|
3855
|
+
(merged, override) => vite2.mergeConfig(merged, override, false),
|
|
3856
|
+
base
|
|
3857
|
+
);
|
|
3780
3858
|
}
|
|
3781
|
-
async function getEnvironmentOptionsResolvers(ctx, buildManifest) {
|
|
3859
|
+
async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
|
|
3782
3860
|
let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
|
|
3783
|
-
|
|
3861
|
+
let packageRoot = path6.dirname(
|
|
3862
|
+
require.resolve("@react-router/dev/package.json")
|
|
3863
|
+
);
|
|
3864
|
+
let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
|
|
3865
|
+
let vite2 = getVite();
|
|
3866
|
+
let viteServerConditions = [
|
|
3867
|
+
...vite2.defaultServerConditions ?? [],
|
|
3868
|
+
...moduleSyncEnabled ? ["module-sync"] : []
|
|
3869
|
+
];
|
|
3870
|
+
function getBaseOptions({
|
|
3784
3871
|
viteUserConfig
|
|
3785
3872
|
}) {
|
|
3786
3873
|
return {
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
userHandler
|
|
3801
|
-
|
|
3802
|
-
|
|
3874
|
+
build: {
|
|
3875
|
+
cssMinify: viteUserConfig.build?.cssMinify ?? true,
|
|
3876
|
+
manifest: true,
|
|
3877
|
+
// The manifest is enabled for all builds to detect SSR-only assets
|
|
3878
|
+
rollupOptions: {
|
|
3879
|
+
preserveEntrySignatures: "exports-only",
|
|
3880
|
+
// Silence Rollup "use client" warnings
|
|
3881
|
+
// Adapted from https://github.com/vitejs/vite-plugin-react/pull/144
|
|
3882
|
+
onwarn(warning, defaultHandler) {
|
|
3883
|
+
if (warning.code === "MODULE_LEVEL_DIRECTIVE" && warning.message.includes("use client")) {
|
|
3884
|
+
return;
|
|
3885
|
+
}
|
|
3886
|
+
let userHandler = viteUserConfig.build?.rollupOptions?.onwarn;
|
|
3887
|
+
if (userHandler) {
|
|
3888
|
+
userHandler(warning, defaultHandler);
|
|
3889
|
+
} else {
|
|
3890
|
+
defaultHandler(warning);
|
|
3891
|
+
}
|
|
3803
3892
|
}
|
|
3804
3893
|
}
|
|
3805
3894
|
}
|
|
3806
3895
|
};
|
|
3807
3896
|
}
|
|
3808
|
-
function
|
|
3897
|
+
function getBaseServerOptions({
|
|
3809
3898
|
viteUserConfig
|
|
3810
3899
|
}) {
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3900
|
+
let conditions = viteCommand === "build" ? viteServerConditions : ["development", ...viteServerConditions];
|
|
3901
|
+
return mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), {
|
|
3902
|
+
resolve: {
|
|
3903
|
+
external: ssrExternals,
|
|
3904
|
+
conditions,
|
|
3905
|
+
externalConditions: conditions
|
|
3906
|
+
},
|
|
3907
|
+
build: {
|
|
3908
|
+
// We move SSR-only assets to client assets. Note that the
|
|
3909
|
+
// SSR build can also emit code-split JS files (e.g. by
|
|
3910
|
+
// dynamic import) under the same assets directory
|
|
3911
|
+
// regardless of "ssrEmitAssets" option, so we also need to
|
|
3912
|
+
// keep these JS files have to be kept as-is.
|
|
3913
|
+
ssrEmitAssets: true,
|
|
3914
|
+
copyPublicDir: false,
|
|
3915
|
+
// Assets in the public directory are only used by the client
|
|
3916
|
+
rollupOptions: {
|
|
3917
|
+
output: {
|
|
3918
|
+
entryFileNames: serverBuildFile,
|
|
3919
|
+
format: serverModuleFormat
|
|
3920
|
+
}
|
|
3824
3921
|
}
|
|
3825
3922
|
}
|
|
3826
3923
|
});
|
|
3827
3924
|
}
|
|
3828
3925
|
let environmentOptionsResolvers = {
|
|
3829
|
-
client: ({ viteUserConfig }) => ({
|
|
3830
|
-
build:
|
|
3926
|
+
client: ({ viteUserConfig }) => mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), {
|
|
3927
|
+
build: {
|
|
3831
3928
|
rollupOptions: {
|
|
3832
3929
|
input: [
|
|
3833
3930
|
ctx.entryClientFilePath,
|
|
3834
|
-
...Object.values(ctx.reactRouterConfig.routes).flatMap(
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3931
|
+
...Object.values(ctx.reactRouterConfig.routes).flatMap(
|
|
3932
|
+
(route) => {
|
|
3933
|
+
let routeFilePath = path6.resolve(
|
|
3934
|
+
ctx.reactRouterConfig.appDirectory,
|
|
3935
|
+
route.file
|
|
3936
|
+
);
|
|
3937
|
+
let isRootRoute = route.file === ctx.reactRouterConfig.routes.root.file;
|
|
3938
|
+
let code = fse.readFileSync(routeFilePath, "utf-8");
|
|
3939
|
+
return [
|
|
3940
|
+
`${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
|
|
3941
|
+
...ctx.reactRouterConfig.future.unstable_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
|
|
3942
|
+
(exportName) => code.includes(exportName) ? getRouteChunkModuleId(routeFilePath, exportName) : null
|
|
3943
|
+
) : []
|
|
3944
|
+
].filter(isNonNullable);
|
|
3945
|
+
}
|
|
3946
|
+
)
|
|
3848
3947
|
],
|
|
3849
3948
|
output: {
|
|
3850
3949
|
entryFileNames({ moduleIds }) {
|
|
@@ -3856,19 +3955,19 @@ async function getEnvironmentOptionsResolvers(ctx, buildManifest) {
|
|
|
3856
3955
|
}
|
|
3857
3956
|
},
|
|
3858
3957
|
outDir: getClientBuildDirectory(ctx.reactRouterConfig)
|
|
3859
|
-
}
|
|
3958
|
+
}
|
|
3860
3959
|
})
|
|
3861
3960
|
};
|
|
3862
3961
|
if (hasServerBundles(buildManifest)) {
|
|
3863
3962
|
for (let [serverBundleId, routes] of Object.entries(
|
|
3864
3963
|
getRoutesByServerBundleId(buildManifest)
|
|
3865
3964
|
)) {
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
}) => (
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
{
|
|
3965
|
+
const serverBundleEnvironmentId = serverBundleId.replaceAll("-", "_");
|
|
3966
|
+
const environmentName = `${SSR_BUNDLE_PREFIX}${serverBundleEnvironmentId}`;
|
|
3967
|
+
environmentOptionsResolvers[environmentName] = ({ viteUserConfig }) => mergeEnvironmentOptions(
|
|
3968
|
+
getBaseServerOptions({ viteUserConfig }),
|
|
3969
|
+
{
|
|
3970
|
+
build: {
|
|
3872
3971
|
outDir: getServerBuildDirectory(ctx, { serverBundleId }),
|
|
3873
3972
|
rollupOptions: {
|
|
3874
3973
|
input: `${virtual.serverBuild.id}?route-ids=${Object.keys(
|
|
@@ -3876,30 +3975,43 @@ async function getEnvironmentOptionsResolvers(ctx, buildManifest) {
|
|
|
3876
3975
|
).join(",")}`
|
|
3877
3976
|
}
|
|
3878
3977
|
}
|
|
3879
|
-
|
|
3880
|
-
|
|
3978
|
+
},
|
|
3979
|
+
// Ensure server bundle environments extend the user's SSR
|
|
3980
|
+
// environment config if it exists
|
|
3981
|
+
viteUserConfig.environments?.ssr ?? {}
|
|
3982
|
+
);
|
|
3881
3983
|
}
|
|
3882
3984
|
} else {
|
|
3883
|
-
environmentOptionsResolvers.ssr = ({ viteUserConfig }) => ({
|
|
3884
|
-
build:
|
|
3985
|
+
environmentOptionsResolvers.ssr = ({ viteUserConfig }) => mergeEnvironmentOptions(getBaseServerOptions({ viteUserConfig }), {
|
|
3986
|
+
build: {
|
|
3885
3987
|
outDir: getServerBuildDirectory(ctx),
|
|
3886
3988
|
rollupOptions: {
|
|
3887
3989
|
input: viteUserConfig.build?.rollupOptions?.input ?? virtual.serverBuild.id
|
|
3888
3990
|
}
|
|
3889
|
-
}
|
|
3991
|
+
}
|
|
3890
3992
|
});
|
|
3891
3993
|
}
|
|
3892
3994
|
return environmentOptionsResolvers;
|
|
3893
3995
|
}
|
|
3894
|
-
|
|
3895
|
-
let
|
|
3896
|
-
let
|
|
3996
|
+
function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
|
|
3997
|
+
let environmentOptions = {};
|
|
3998
|
+
for (let [environmentName, resolver] of Object.entries(
|
|
3999
|
+
environmentResolvers
|
|
4000
|
+
)) {
|
|
4001
|
+
environmentOptions[environmentName] = resolver(resolverOptions);
|
|
4002
|
+
}
|
|
4003
|
+
return environmentOptions;
|
|
4004
|
+
}
|
|
4005
|
+
async function getEnvironmentsOptions(ctx, buildManifest, viteCommand, resolverOptions) {
|
|
4006
|
+
let environmentOptionsResolvers = await getEnvironmentOptionsResolvers(
|
|
3897
4007
|
ctx,
|
|
3898
|
-
buildManifest
|
|
4008
|
+
buildManifest,
|
|
4009
|
+
viteCommand
|
|
4010
|
+
);
|
|
4011
|
+
return resolveEnvironmentsOptions(
|
|
4012
|
+
environmentOptionsResolvers,
|
|
4013
|
+
resolverOptions
|
|
3899
4014
|
);
|
|
3900
|
-
let resolver = environmentResolvers[environmentName];
|
|
3901
|
-
invariant(resolver, `Missing environment resolver for ${environmentName}`);
|
|
3902
|
-
return resolver(resolverOptions);
|
|
3903
4015
|
}
|
|
3904
4016
|
function isNonNullable(x) {
|
|
3905
4017
|
return x != null;
|