vinext 0.2.0 → 1.0.0-beta.0
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/README.md +50 -29
- package/dist/build/client-build-config.d.ts +13 -92
- package/dist/build/client-build-config.js +17 -95
- package/dist/build/css-url-assets.d.ts +3 -1
- package/dist/build/css-url-assets.js +18 -1
- package/dist/build/inject-pregenerated-paths.d.ts +3 -0
- package/dist/build/inject-pregenerated-paths.js +4 -1
- package/dist/build/prerender-paths.d.ts +23 -0
- package/dist/build/prerender-paths.js +296 -0
- package/dist/build/prerender-server-entry.d.ts +1 -0
- package/dist/build/prerender-server-entry.js +49 -0
- package/dist/build/prerender-server-pool.d.ts +44 -0
- package/dist/build/prerender-server-pool.js +194 -0
- package/dist/build/prerender.d.ts +12 -1
- package/dist/build/prerender.js +87 -23
- package/dist/build/run-prerender.js +2 -1
- package/dist/cache/cache-adapters-virtual.d.ts +7 -1
- package/dist/cache/cache-adapters-virtual.js +26 -2
- package/dist/check.d.ts +4 -6
- package/dist/check.js +13 -9
- package/dist/cli.js +34 -54
- package/dist/client/vinext-next-data.d.ts +4 -1
- package/dist/config/config-matchers.js +33 -11
- package/dist/config/next-config.d.ts +36 -6
- package/dist/config/next-config.js +17 -4
- package/dist/config/prerender.d.ts +11 -1
- package/dist/config/prerender.js +19 -1
- package/dist/config/tsconfig-paths.js +5 -1
- package/dist/entries/app-browser-entry.js +5 -1
- package/dist/entries/app-rsc-entry.d.ts +3 -2
- package/dist/entries/app-rsc-entry.js +4 -0
- package/dist/entries/pages-client-entry.js +14 -3
- package/dist/entries/pages-server-entry.js +18 -4
- package/dist/image/image-adapters-virtual.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +549 -152
- package/dist/init-cloudflare.js +12 -3
- package/dist/init-platform.d.ts +10 -1
- package/dist/init-platform.js +78 -12
- package/dist/init.d.ts +11 -3
- package/dist/init.js +129 -31
- package/dist/plugins/fonts.js +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +1 -1
- package/dist/plugins/og-assets.js +2 -1
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
- package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
- package/dist/plugins/sass.d.ts +17 -1
- package/dist/plugins/sass.js +74 -1
- package/dist/plugins/styled-jsx.d.ts +16 -0
- package/dist/plugins/styled-jsx.js +149 -0
- package/dist/routing/app-route-graph.js +22 -16
- package/dist/routing/file-matcher.d.ts +8 -1
- package/dist/routing/file-matcher.js +15 -3
- package/dist/server/app-browser-entry.js +44 -14
- package/dist/server/app-browser-navigation-controller.js +5 -2
- package/dist/server/app-browser-server-action-client.js +5 -3
- package/dist/server/app-browser-state.d.ts +1 -0
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-layout-param-observation.d.ts +1 -1
- package/dist/server/app-page-boundary.js +2 -1
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +3 -3
- package/dist/server/app-page-cache-render.d.ts +1 -1
- package/dist/server/app-page-cache.js +23 -6
- package/dist/server/app-page-dispatch.d.ts +2 -1
- package/dist/server/app-page-dispatch.js +27 -10
- package/dist/server/app-page-element-builder.js +1 -0
- package/dist/server/app-page-execution.js +2 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +2 -1
- package/dist/server/app-page-render.d.ts +3 -1
- package/dist/server/app-page-render.js +67 -16
- package/dist/server/app-page-response.d.ts +7 -0
- package/dist/server/app-page-response.js +16 -4
- package/dist/server/app-page-route-wiring.js +3 -3
- package/dist/server/app-page-stream.d.ts +2 -1
- package/dist/server/app-page-stream.js +1 -1
- package/dist/server/app-route-handler-execution.d.ts +1 -1
- package/dist/server/app-route-tree-prefetch.d.ts +43 -0
- package/dist/server/app-route-tree-prefetch.js +187 -0
- package/dist/server/app-router-entry.js +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +2 -1
- package/dist/server/app-rsc-cache-busting.js +9 -5
- package/dist/server/app-rsc-handler.d.ts +6 -0
- package/dist/server/app-rsc-handler.js +88 -10
- package/dist/server/app-rsc-render-mode.d.ts +3 -5
- package/dist/server/app-rsc-render-mode.js +5 -12
- package/dist/server/app-rsc-request-normalization.d.ts +3 -4
- package/dist/server/app-rsc-request-normalization.js +4 -5
- package/dist/server/app-server-action-execution.js +6 -5
- package/dist/server/app-ssr-entry.js +1 -1
- package/dist/server/cache-control.d.ts +3 -1
- package/dist/server/cache-control.js +13 -1
- package/dist/server/dev-module-runner.js +1 -1
- package/dist/server/dev-origin-check.d.ts +2 -2
- package/dist/server/dev-origin-check.js +2 -2
- package/dist/server/dev-server.d.ts +11 -1
- package/dist/server/dev-server.js +82 -24
- package/dist/server/headers.d.ts +6 -2
- package/dist/server/headers.js +11 -5
- package/dist/server/image-optimization.d.ts +12 -1
- package/dist/server/image-optimization.js +13 -1
- package/dist/server/isr-cache.d.ts +13 -4
- package/dist/server/isr-cache.js +8 -4
- package/dist/server/pages-data-route.d.ts +4 -2
- package/dist/server/pages-data-route.js +18 -4
- package/dist/server/pages-dev-module-url.d.ts +2 -1
- package/dist/server/pages-dev-module-url.js +6 -3
- package/dist/server/pages-node-compat.d.ts +12 -1
- package/dist/server/pages-node-compat.js +50 -1
- package/dist/server/pages-page-data.d.ts +9 -0
- package/dist/server/pages-page-data.js +18 -10
- package/dist/server/pages-page-handler.js +19 -7
- package/dist/server/pages-page-response.d.ts +1 -0
- package/dist/server/pages-page-response.js +5 -4
- package/dist/server/pages-request-pipeline.d.ts +8 -6
- package/dist/server/pages-request-pipeline.js +31 -7
- package/dist/server/pages-router-entry.js +1 -1
- package/dist/server/prerender-manifest.d.ts +15 -1
- package/dist/server/prerender-manifest.js +29 -1
- package/dist/server/prod-server.d.ts +10 -7
- package/dist/server/prod-server.js +43 -28
- package/dist/server/request-pipeline.js +1 -1
- package/dist/server/static-file-cache.js +1 -1
- package/dist/shims/cache-handler.js +8 -1
- package/dist/shims/cache.d.ts +1 -1
- package/dist/shims/cache.js +3 -0
- package/dist/shims/cdn-cache.d.ts +2 -7
- package/dist/shims/cdn-cache.js +2 -14
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +77 -52
- package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
- package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -1
- package/dist/shims/internal/hybrid-client-route-owner.js +34 -1
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +2 -1
- package/dist/shims/internal/pages-data-fetch-dedup.js +13 -2
- package/dist/shims/internal/pages-data-target.d.ts +8 -3
- package/dist/shims/internal/pages-data-target.js +9 -4
- package/dist/shims/link.d.ts +1 -1
- package/dist/shims/link.js +179 -42
- package/dist/shims/navigation.d.ts +15 -3
- package/dist/shims/navigation.js +202 -39
- package/dist/shims/request-context.js +18 -0
- package/dist/shims/request-state-types.d.ts +2 -2
- package/dist/shims/router.js +31 -15
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -1
- package/dist/utils/middleware-request-headers.js +1 -1
- package/dist/utils/project.d.ts +1 -1
- package/dist/utils/protocol-headers.d.ts +7 -1
- package/dist/utils/protocol-headers.js +7 -1
- package/dist/utils/vite-version.d.ts +4 -12
- package/dist/utils/vite-version.js +39 -21
- package/package.json +31 -13
- package/dist/cloudflare/index.d.ts +0 -3
- package/dist/cloudflare/index.js +0 -3
- package/dist/packages/cloudflare/src/cache/cdn-adapter.runtime.js +0 -102
- package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +0 -126
- package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.js +0 -435
- package/dist/packages/cloudflare/src/deploy-config.js +0 -150
- package/dist/packages/cloudflare/src/deploy-help.js +0 -55
- package/dist/packages/cloudflare/src/deploy.js +0 -276
- package/dist/packages/cloudflare/src/tpr.d.ts +0 -45
- package/dist/packages/cloudflare/src/tpr.js +0 -561
- package/dist/packages/cloudflare/src/utils/cache-control-metadata.js +0 -20
|
@@ -6,6 +6,7 @@ type VinextLinkPrefetchRoute = {
|
|
|
6
6
|
documentOnly?: boolean;
|
|
7
7
|
isDynamic: boolean;
|
|
8
8
|
patternParts: string[];
|
|
9
|
+
requiresDynamicNavigationRequest?: boolean;
|
|
9
10
|
};
|
|
10
11
|
/**
|
|
11
12
|
* Pages Router route pattern exposed to the client so the App Router's
|
|
@@ -22,13 +23,15 @@ type VinextPagesLinkPrefetchRoute = {
|
|
|
22
23
|
documentOnly?: boolean;
|
|
23
24
|
isDynamic: boolean;
|
|
24
25
|
patternParts: string[];
|
|
26
|
+
requiresDynamicNavigationRequest?: boolean;
|
|
25
27
|
};
|
|
26
28
|
type VinextNextData = {
|
|
27
29
|
/** vinext-specific additions (not part of Next.js upstream). */__vinext?: {
|
|
28
30
|
/** Absolute URL of the page module for dynamic import. */pageModuleUrl?: string; /** Absolute URL of the `_app` module for dynamic import. */
|
|
29
31
|
appModuleUrl?: string; /** True when the Pages Router server has middleware/proxy configured. */
|
|
30
32
|
hasMiddleware?: boolean; /** True when build-time rewrites can affect the initial Pages Router ready state. */
|
|
31
|
-
hasRewrites?: boolean;
|
|
33
|
+
hasRewrites?: boolean; /** Server-resolved Pages route URL used to hydrate fallback shells behind rewrites. */
|
|
34
|
+
routeUrl?: string;
|
|
32
35
|
};
|
|
33
36
|
} & NEXT_DATA;
|
|
34
37
|
type BrowserVinextNextData = NonNullable<Window["__NEXT_DATA__"]> & VinextNextData;
|
|
@@ -133,7 +133,7 @@ function _getRedirectIndex(redirects) {
|
|
|
133
133
|
const alternation = m[1];
|
|
134
134
|
const optional = m[2] === "?";
|
|
135
135
|
const suffix = "/" + m[3];
|
|
136
|
-
const altRe = safeRegExp("^(?:" + alternation + ")$");
|
|
136
|
+
const altRe = safeRegExp("^(?:" + alternation + ")$", "i");
|
|
137
137
|
if (!altRe) {
|
|
138
138
|
linear.push([i, redirect]);
|
|
139
139
|
continue;
|
|
@@ -145,9 +145,10 @@ function _getRedirectIndex(redirects) {
|
|
|
145
145
|
redirect,
|
|
146
146
|
originalIndex: i
|
|
147
147
|
};
|
|
148
|
-
const
|
|
148
|
+
const bucketKey = suffix.toLowerCase();
|
|
149
|
+
const bucket = localeStatic.get(bucketKey);
|
|
149
150
|
if (bucket) bucket.push(entry);
|
|
150
|
-
else localeStatic.set(
|
|
151
|
+
else localeStatic.set(bucketKey, [entry]);
|
|
151
152
|
} else linear.push([i, redirect]);
|
|
152
153
|
}
|
|
153
154
|
index = {
|
|
@@ -393,7 +394,7 @@ function normalizeHost(hostHeader, fallbackHostname) {
|
|
|
393
394
|
*/
|
|
394
395
|
function applyMiddlewareRequestHeaders(middlewareHeaders, request, options = {}) {
|
|
395
396
|
const nextHeaders = buildRequestHeadersFromMiddlewareResponse(request.headers, middlewareHeaders, options);
|
|
396
|
-
for (const key of Object.keys(middlewareHeaders)) if (key.startsWith("x-middleware-")) delete middlewareHeaders[key];
|
|
397
|
+
for (const key of Object.keys(middlewareHeaders)) if (key.startsWith("x-middleware-") && key !== "x-middleware-cache") delete middlewareHeaders[key];
|
|
397
398
|
if (nextHeaders) request = new Request(request.url, {
|
|
398
399
|
method: request.method,
|
|
399
400
|
headers: nextHeaders,
|
|
@@ -529,6 +530,12 @@ function extractConstraint(str, re) {
|
|
|
529
530
|
function stripTrailingSlashForConfigMatch(value) {
|
|
530
531
|
return value.length > 1 && value.endsWith("/") ? value.slice(0, -1) : value;
|
|
531
532
|
}
|
|
533
|
+
function configPathEquals(a, b) {
|
|
534
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
535
|
+
}
|
|
536
|
+
function configPathStartsWith(pathname, prefix) {
|
|
537
|
+
return pathname.slice(0, prefix.length).toLowerCase() === prefix.toLowerCase();
|
|
538
|
+
}
|
|
532
539
|
function matchConfigPattern(pathname, pattern) {
|
|
533
540
|
const pathnameHadTrailingSlash = pathname.length > 1 && pathname.endsWith("/");
|
|
534
541
|
pathname = stripTrailingSlashForConfigMatch(pathname);
|
|
@@ -558,7 +565,7 @@ function matchConfigPattern(pathname, pattern) {
|
|
|
558
565
|
}
|
|
559
566
|
} else if (tok[0] === ".") regexStr += "\\.";
|
|
560
567
|
else regexStr += tok[0];
|
|
561
|
-
const re = safeRegExp("^" + regexStr + "$");
|
|
568
|
+
const re = safeRegExp("^" + regexStr + "$", "i");
|
|
562
569
|
return re ? {
|
|
563
570
|
re,
|
|
564
571
|
paramNames
|
|
@@ -577,7 +584,7 @@ function matchConfigPattern(pathname, pattern) {
|
|
|
577
584
|
const paramName = catchAllMatch[1];
|
|
578
585
|
const isPlus = catchAllMatch[2] === "+";
|
|
579
586
|
const prefixNoSlash = prefix.replace(/\/$/, "");
|
|
580
|
-
if (!pathname
|
|
587
|
+
if (!configPathStartsWith(pathname, prefixNoSlash)) return null;
|
|
581
588
|
const charAfter = pathname[prefixNoSlash.length];
|
|
582
589
|
if (charAfter !== void 0 && charAfter !== "/") return null;
|
|
583
590
|
const rest = pathname.slice(prefixNoSlash.length);
|
|
@@ -590,7 +597,7 @@ function matchConfigPattern(pathname, pattern) {
|
|
|
590
597
|
if (parts.length !== pathParts.length) return null;
|
|
591
598
|
const params = Object.create(null);
|
|
592
599
|
for (let i = 0; i < parts.length; i++) if (parts[i].startsWith(":")) params[parts[i].slice(1)] = pathParts[i];
|
|
593
|
-
else if (parts[i]
|
|
600
|
+
else if (!configPathEquals(parts[i], pathParts[i])) return null;
|
|
594
601
|
return params;
|
|
595
602
|
}
|
|
596
603
|
/**
|
|
@@ -635,7 +642,7 @@ function matchRedirect(pathname, redirects, ctx, basePathState = _BASEPATH_DEFAU
|
|
|
635
642
|
let localeMatch = null;
|
|
636
643
|
let localeMatchIndex = Infinity;
|
|
637
644
|
if (index.localeStatic.size > 0) {
|
|
638
|
-
const noLocaleBucket = index.localeStatic.get(normalizedPathname);
|
|
645
|
+
const noLocaleBucket = index.localeStatic.get(normalizedPathname.toLowerCase());
|
|
639
646
|
if (noLocaleBucket) for (const entry of noLocaleBucket) {
|
|
640
647
|
if (!entry.optional) continue;
|
|
641
648
|
if (entry.originalIndex >= localeMatchIndex) continue;
|
|
@@ -657,7 +664,7 @@ function matchRedirect(pathname, redirects, ctx, basePathState = _BASEPATH_DEFAU
|
|
|
657
664
|
if (slashTwo !== -1) {
|
|
658
665
|
const suffix = normalizedPathname.slice(slashTwo);
|
|
659
666
|
const localePart = normalizedPathname.slice(1, slashTwo);
|
|
660
|
-
const localeBucket = index.localeStatic.get(suffix);
|
|
667
|
+
const localeBucket = index.localeStatic.get(suffix.toLowerCase());
|
|
661
668
|
if (localeBucket) for (const entry of localeBucket) {
|
|
662
669
|
if (entry.originalIndex >= localeMatchIndex) continue;
|
|
663
670
|
if (!entry.altRe.test(localePart)) continue;
|
|
@@ -748,7 +755,22 @@ function substituteDestinationParams(destination, params) {
|
|
|
748
755
|
paramRe = new RegExp(`:(${paramAlternation})([+*])?(?![A-Za-z0-9_])`, "g");
|
|
749
756
|
_compiledDestinationParamCache.set(cacheKey, paramRe);
|
|
750
757
|
}
|
|
751
|
-
|
|
758
|
+
const replaceParams = (value, encodeParam) => value.replace(paramRe, (_token, key) => encodeParam(params[key]));
|
|
759
|
+
const hashIndex = destination.indexOf("#");
|
|
760
|
+
const beforeHash = hashIndex === -1 ? destination : destination.slice(0, hashIndex);
|
|
761
|
+
const hash = hashIndex === -1 ? "" : destination.slice(hashIndex);
|
|
762
|
+
const queryIndex = beforeHash.indexOf("?");
|
|
763
|
+
if (queryIndex !== -1) {
|
|
764
|
+
const beforeQuery = beforeHash.slice(0, queryIndex);
|
|
765
|
+
const query = beforeHash.slice(queryIndex + 1);
|
|
766
|
+
return `${replaceParams(beforeQuery, (value) => value)}?${replaceParams(query, encodeDestinationQueryParamValue)}${replaceParams(hash, (value) => value)}`;
|
|
767
|
+
}
|
|
768
|
+
return replaceParams(destination, (value) => value);
|
|
769
|
+
}
|
|
770
|
+
function encodeDestinationQueryParamValue(value) {
|
|
771
|
+
const params = new URLSearchParams();
|
|
772
|
+
params.set("", value);
|
|
773
|
+
return params.toString().slice(1);
|
|
752
774
|
}
|
|
753
775
|
/**
|
|
754
776
|
* Substitute params into a redirect/rewrite destination and sanitize the
|
|
@@ -964,7 +986,7 @@ function matchHeaders(pathname, headers, ctx, basePathState = _BASEPATH_DEFAULT)
|
|
|
964
986
|
for (const rule of headers) {
|
|
965
987
|
if (!shouldEvaluateRule(rule.basePath, basePathState)) continue;
|
|
966
988
|
const source = pathnameHadTrailingSlash ? stripTrailingSlashForConfigMatch(rule.source) : rule.source;
|
|
967
|
-
const sourceRegex = getCachedRegex(_compiledHeaderSourceCache, source, () => safeRegExp("^" + escapeHeaderSource(source) + "$"));
|
|
989
|
+
const sourceRegex = getCachedRegex(_compiledHeaderSourceCache, source, () => safeRegExp("^" + escapeHeaderSource(source) + "$", "i"));
|
|
968
990
|
if (sourceRegex && sourceRegex.test(pathname)) {
|
|
969
991
|
if (rule.has || rule.missing) {
|
|
970
992
|
if (!checkHasConditions(rule.has, rule.missing, ctx)) continue;
|
|
@@ -82,6 +82,10 @@ type MdxOptions = {
|
|
|
82
82
|
rehypePlugins?: unknown[];
|
|
83
83
|
recmaPlugins?: unknown[];
|
|
84
84
|
};
|
|
85
|
+
type PrefetchInliningConfig = false | {
|
|
86
|
+
maxBundleSize: number;
|
|
87
|
+
maxSize: number;
|
|
88
|
+
};
|
|
85
89
|
type NextConfig = {
|
|
86
90
|
/** Additional env variables */env?: Record<string, string>; /** Base URL path prefix */
|
|
87
91
|
basePath?: string;
|
|
@@ -123,7 +127,15 @@ type NextConfig = {
|
|
|
123
127
|
dangerouslyAllowLocalIP?: boolean; /** Content-Disposition header for image responses. Defaults to "inline". */
|
|
124
128
|
contentDispositionType?: "inline" | "attachment"; /** Content-Security-Policy header for image responses. Defaults to "script-src 'none'; frame-src 'none'; sandbox;" */
|
|
125
129
|
contentSecurityPolicy?: string;
|
|
126
|
-
};
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Enable React Strict Mode. When `true`, the client root is wrapped in
|
|
133
|
+
* `<React.StrictMode>` so React runs its dev-only strict checks (double-
|
|
134
|
+
* invoked effects/render, deprecation warnings). `null`/unset resolves per
|
|
135
|
+
* router: OFF for the Pages Router, ON for the App Router — matching Next.js.
|
|
136
|
+
* @see https://nextjs.org/docs/app/api-reference/config/next-config-js/reactStrictMode
|
|
137
|
+
*/
|
|
138
|
+
reactStrictMode?: boolean | null; /** Build output mode: 'export' for full static export, 'standalone' for single server */
|
|
127
139
|
output?: "export" | "standalone"; /** File extensions treated as routable pages/routes (Next.js pageExtensions) */
|
|
128
140
|
pageExtensions?: string[]; /** Turbopack-compatible module resolution options. */
|
|
129
141
|
turbopack?: {
|
|
@@ -194,6 +206,15 @@ type NextConfig = {
|
|
|
194
206
|
* `useRouter().experimental_gesturePush()`.
|
|
195
207
|
*/
|
|
196
208
|
gestureTransition?: boolean;
|
|
209
|
+
/**
|
|
210
|
+
* Enables App Router Segment Cache prefetch inlining. When provided as an
|
|
211
|
+
* object, thresholds are resolved with Next.js defaults and non-finite
|
|
212
|
+
* values are clamped to Number.MAX_SAFE_INTEGER.
|
|
213
|
+
*/
|
|
214
|
+
prefetchInlining?: boolean | {
|
|
215
|
+
maxBundleSize?: number;
|
|
216
|
+
maxSize?: number;
|
|
217
|
+
};
|
|
197
218
|
[key: string]: unknown;
|
|
198
219
|
};
|
|
199
220
|
/**
|
|
@@ -254,11 +275,10 @@ type ResolvedNextConfig = {
|
|
|
254
275
|
*/
|
|
255
276
|
gestureTransition: boolean;
|
|
256
277
|
/**
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* segment payload.
|
|
278
|
+
* Resolved `experimental.prefetchInlining` config. Next.js normalizes `true`
|
|
279
|
+
* and partial object config into concrete thresholds.
|
|
260
280
|
*/
|
|
261
|
-
prefetchInlining:
|
|
281
|
+
prefetchInlining: PrefetchInliningConfig;
|
|
262
282
|
redirects: NextRedirect[];
|
|
263
283
|
rewrites: {
|
|
264
284
|
beforeFiles: NextRewrite[];
|
|
@@ -350,6 +370,16 @@ type ResolvedNextConfig = {
|
|
|
350
370
|
* `test/e2e/optimized-loading` test fixture.
|
|
351
371
|
*/
|
|
352
372
|
disableOptimizedLoading: boolean;
|
|
373
|
+
/**
|
|
374
|
+
* Resolved `reactStrictMode` from next.config, preserved as `boolean | null`
|
|
375
|
+
* so each router can apply its own default (Next.js resolves `null` to OFF
|
|
376
|
+
* for the Pages Router and ON for the App Router). When the effective value
|
|
377
|
+
* is `true`, the client root is wrapped in `<React.StrictMode>`.
|
|
378
|
+
*
|
|
379
|
+
* See `.nextjs-ref/packages/next/src/build/define-env.ts`
|
|
380
|
+
* (`__NEXT_STRICT_MODE` / `__NEXT_STRICT_MODE_APP`).
|
|
381
|
+
*/
|
|
382
|
+
reactStrictMode: boolean | null;
|
|
353
383
|
/**
|
|
354
384
|
* Mirrors Next.js `experimental.scrollRestoration`. When true, the Pages
|
|
355
385
|
* Router client takes ownership of browser history scroll restoration by
|
|
@@ -534,4 +564,4 @@ declare function extractMdxOptions(config: NextConfig, root?: string): Promise<M
|
|
|
534
564
|
*/
|
|
535
565
|
declare function detectNextIntlConfig(root: string, resolved: ResolvedNextConfig): void;
|
|
536
566
|
//#endregion
|
|
537
|
-
export { HasCondition, MdxOptions, NextConfig, NextConfigInput, NextHeader, NextI18nConfig, NextRedirect, NextRewrite, PHASE_PRODUCTION_BUILD, ResolvedNextConfig, createRscCompatibilityId, detectNextIntlConfig, extractMdxOptions, findNextConfigPath, lightningCssFeatureNamesToMask, loadNextConfig, normalizeAssetPrefix, parseBodySizeLimit, reassignsModuleExports, referencesCjsGlobals, resolveNextConfig, resolveNextConfigInput };
|
|
567
|
+
export { HasCondition, MdxOptions, NextConfig, NextConfigInput, NextHeader, NextI18nConfig, NextRedirect, NextRewrite, PHASE_PRODUCTION_BUILD, PrefetchInliningConfig, ResolvedNextConfig, createRscCompatibilityId, detectNextIntlConfig, extractMdxOptions, findNextConfigPath, lightningCssFeatureNamesToMask, loadNextConfig, normalizeAssetPrefix, parseBodySizeLimit, reassignsModuleExports, referencesCjsGlobals, resolveNextConfig, resolveNextConfigInput };
|
|
@@ -4,7 +4,6 @@ import { isUnknownRecord } from "../utils/record.js";
|
|
|
4
4
|
import { getHtmlLimitedBotRegex } from "../utils/html-limited-bots.js";
|
|
5
5
|
import { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } from "../shims/constants.js";
|
|
6
6
|
import { loadTsconfigResolutionForRoot } from "./tsconfig-paths.js";
|
|
7
|
-
import { getViteMajorVersion } from "../utils/vite-version.js";
|
|
8
7
|
import { loadCommonJsModule, shouldRetryAsCommonJs } from "../utils/commonjs-loader.js";
|
|
9
8
|
import { createRequire } from "node:module";
|
|
10
9
|
import fs from "node:fs";
|
|
@@ -315,7 +314,7 @@ async function loadNextConfig(root, phase = DEFAULT_PHASE) {
|
|
|
315
314
|
const filename = path.basename(configPath);
|
|
316
315
|
const isTypeScriptConfig = /\.[cm]?ts$/.test(configPath);
|
|
317
316
|
const tsconfigResolution = loadTsconfigResolutionForRoot(root);
|
|
318
|
-
const useNativeTsconfigPaths = !!(isTypeScriptConfig ? tsconfigResolution.baseUrl : null)
|
|
317
|
+
const useNativeTsconfigPaths = !!(isTypeScriptConfig ? tsconfigResolution.baseUrl : null);
|
|
319
318
|
const normalizedConfigPath = safeRealpath(path.resolve(configPath));
|
|
320
319
|
try {
|
|
321
320
|
const { runnerImport } = await import("vite");
|
|
@@ -560,6 +559,18 @@ function resolveStaleTimes(experimental) {
|
|
|
560
559
|
static: Number.isFinite(staticRaw) && staticRaw >= 0 ? staticRaw : DEFAULT_STALE_TIMES.static
|
|
561
560
|
};
|
|
562
561
|
}
|
|
562
|
+
function normalizePrefetchInliningConfig(value) {
|
|
563
|
+
if (!value) return false;
|
|
564
|
+
const raw = isUnknownRecord(value) ? value : null;
|
|
565
|
+
const maxSize = raw ? raw.maxSize ?? 2048 : 2048;
|
|
566
|
+
const maxBundleSize = raw ? raw.maxBundleSize ?? 10240 : 10240;
|
|
567
|
+
const normalizedMaxSize = Number(maxSize);
|
|
568
|
+
const normalizedMaxBundleSize = Number(maxBundleSize);
|
|
569
|
+
return {
|
|
570
|
+
maxBundleSize: Number.isFinite(normalizedMaxBundleSize) ? normalizedMaxBundleSize : Number.MAX_SAFE_INTEGER,
|
|
571
|
+
maxSize: Number.isFinite(normalizedMaxSize) ? normalizedMaxSize : Number.MAX_SAFE_INTEGER
|
|
572
|
+
};
|
|
573
|
+
}
|
|
563
574
|
/**
|
|
564
575
|
* Resolve a NextConfig into a fully-resolved ResolvedNextConfig.
|
|
565
576
|
* Awaits async functions for redirects/rewrites/headers.
|
|
@@ -615,6 +626,7 @@ async function resolveNextConfig(config, root = process.cwd(), options = {}) {
|
|
|
615
626
|
sassOptions: null,
|
|
616
627
|
removeConsole: false,
|
|
617
628
|
disableOptimizedLoading: false,
|
|
629
|
+
reactStrictMode: null,
|
|
618
630
|
scrollRestoration: false,
|
|
619
631
|
compilerDefine: {},
|
|
620
632
|
compilerDefineServer: {},
|
|
@@ -683,12 +695,12 @@ async function resolveNextConfig(config, root = process.cwd(), options = {}) {
|
|
|
683
695
|
const optimizePackageImports = Array.isArray(rawOptimize) ? rawOptimize.filter((x) => typeof x === "string") : [];
|
|
684
696
|
const inlineCss = experimental?.inlineCss === true;
|
|
685
697
|
const globalNotFound = experimental?.globalNotFound === true;
|
|
686
|
-
const prefetchInlining =
|
|
698
|
+
const prefetchInlining = normalizePrefetchInliningConfig(experimental?.prefetchInlining);
|
|
687
699
|
const appShells = experimental?.appShells === true;
|
|
688
700
|
if (appShells) {
|
|
689
701
|
const missingCoFlags = [];
|
|
690
702
|
if (!config.cacheComponents) missingCoFlags.push("cacheComponents");
|
|
691
|
-
if (
|
|
703
|
+
if (!prefetchInlining) missingCoFlags.push("experimental.prefetchInlining");
|
|
692
704
|
if (experimental?.varyParams !== true) missingCoFlags.push("experimental.varyParams");
|
|
693
705
|
if (experimental?.optimisticRouting !== true) missingCoFlags.push("experimental.optimisticRouting");
|
|
694
706
|
if (experimental?.cachedNavigations !== true) missingCoFlags.push("experimental.cachedNavigations");
|
|
@@ -791,6 +803,7 @@ async function resolveNextConfig(config, root = process.cwd(), options = {}) {
|
|
|
791
803
|
sassOptions: readOptionalRecord(config.sassOptions) ?? null,
|
|
792
804
|
removeConsole: config.compiler?.removeConsole === true ? true : isUnknownRecord(config.compiler?.removeConsole) ? { exclude: readStringArray(config.compiler.removeConsole.exclude) } : false,
|
|
793
805
|
disableOptimizedLoading: experimental?.disableOptimizedLoading === true,
|
|
806
|
+
reactStrictMode: typeof config.reactStrictMode === "boolean" ? config.reactStrictMode : null,
|
|
794
807
|
scrollRestoration: experimental?.scrollRestoration === true,
|
|
795
808
|
compilerDefine: serializeCompilerDefine(config.compiler?.define),
|
|
796
809
|
compilerDefineServer: serializeCompilerDefine(config.compiler?.defineServer),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { VINEXT_CACHE_CONFIG_PLUGIN_PROPERTY, VinextCacheConfig, findVinextCacheConfigInPlugins, loadVinextCacheConfigFromViteConfig } from "../cache/cache-adapters-virtual.js";
|
|
1
2
|
import { PluginOption } from "vite";
|
|
2
3
|
|
|
3
4
|
//#region src/config/prerender.d.ts
|
|
@@ -18,12 +19,21 @@ type VinextPrerenderDecision = ResolvedVinextPrerenderConfig & {
|
|
|
18
19
|
reason: VinextPrerenderDecisionReason;
|
|
19
20
|
};
|
|
20
21
|
declare const VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY = "__vinextPrerenderConfig";
|
|
22
|
+
declare const VINEXT_ROUTE_ROOT_CONFIG_PLUGIN_PROPERTY = "__vinextRouteRootConfig";
|
|
23
|
+
type VinextRouteRootConfig = {
|
|
24
|
+
appDir?: string;
|
|
25
|
+
disableAppRouter?: boolean;
|
|
26
|
+
rscOutDir?: string;
|
|
27
|
+
ssrOutDir?: string;
|
|
28
|
+
};
|
|
21
29
|
type ViteConfigLoader = {
|
|
22
30
|
loadConfigFromFile: typeof import("vite").loadConfigFromFile;
|
|
23
31
|
};
|
|
24
32
|
declare function normalizeVinextPrerenderConfig(config: VinextPrerenderConfig | undefined): ResolvedVinextPrerenderConfig | null;
|
|
25
33
|
declare function findVinextPrerenderConfigInPlugins(plugins: PluginOption[] | undefined): ResolvedVinextPrerenderConfig | null;
|
|
34
|
+
declare function findVinextRouteRootConfigInPlugins(plugins: PluginOption[] | undefined): VinextRouteRootConfig | null;
|
|
26
35
|
declare function loadVinextPrerenderConfigFromViteConfig(vite: ViteConfigLoader, root: string): Promise<ResolvedVinextPrerenderConfig | null>;
|
|
36
|
+
declare function loadVinextRouteRootConfigFromViteConfig(vite: ViteConfigLoader, root: string): Promise<VinextRouteRootConfig | null>;
|
|
27
37
|
declare function resolveVinextPrerenderDecision(options: {
|
|
28
38
|
prerenderAllFlag?: boolean;
|
|
29
39
|
vinextPrerenderConfig?: ResolvedVinextPrerenderConfig | null;
|
|
@@ -31,4 +41,4 @@ declare function resolveVinextPrerenderDecision(options: {
|
|
|
31
41
|
}): VinextPrerenderDecision | null;
|
|
32
42
|
declare function formatVinextPrerenderLabel(decision: VinextPrerenderDecision): string;
|
|
33
43
|
//#endregion
|
|
34
|
-
export { ResolvedVinextPrerenderConfig, VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY, VinextPrerenderConfig, VinextPrerenderDecision, VinextPrerenderDecisionReason, findVinextPrerenderConfigInPlugins, formatVinextPrerenderLabel, loadVinextPrerenderConfigFromViteConfig, normalizeVinextPrerenderConfig, resolveVinextPrerenderDecision };
|
|
44
|
+
export { ResolvedVinextPrerenderConfig, VINEXT_CACHE_CONFIG_PLUGIN_PROPERTY, VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY, VINEXT_ROUTE_ROOT_CONFIG_PLUGIN_PROPERTY, type VinextCacheConfig, VinextPrerenderConfig, VinextPrerenderDecision, VinextPrerenderDecisionReason, VinextRouteRootConfig, findVinextCacheConfigInPlugins, findVinextPrerenderConfigInPlugins, findVinextRouteRootConfigInPlugins, formatVinextPrerenderLabel, loadVinextCacheConfigFromViteConfig, loadVinextPrerenderConfigFromViteConfig, loadVinextRouteRootConfigFromViteConfig, normalizeVinextPrerenderConfig, resolveVinextPrerenderDecision };
|
package/dist/config/prerender.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { isUnknownRecord } from "../utils/record.js";
|
|
2
|
+
import { VINEXT_CACHE_CONFIG_PLUGIN_PROPERTY, findVinextCacheConfigInPlugins, loadVinextCacheConfigFromViteConfig } from "../cache/cache-adapters-virtual.js";
|
|
2
3
|
//#region src/config/prerender.ts
|
|
3
4
|
const VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY = "__vinextPrerenderConfig";
|
|
5
|
+
const VINEXT_ROUTE_ROOT_CONFIG_PLUGIN_PROPERTY = "__vinextRouteRootConfig";
|
|
4
6
|
function normalizeVinextPrerenderConfig(config) {
|
|
5
7
|
if (config === void 0) return null;
|
|
6
8
|
if (config === true) return { routes: "*" };
|
|
@@ -25,12 +27,28 @@ function findVinextPrerenderConfigInPlugins(plugins) {
|
|
|
25
27
|
}
|
|
26
28
|
return null;
|
|
27
29
|
}
|
|
30
|
+
function findVinextRouteRootConfigInPlugins(plugins) {
|
|
31
|
+
const flattened = [];
|
|
32
|
+
flattenPluginOptions(plugins, flattened);
|
|
33
|
+
for (const plugin of flattened) {
|
|
34
|
+
if (!isUnknownRecord(plugin)) continue;
|
|
35
|
+
const routeRootConfig = plugin[VINEXT_ROUTE_ROOT_CONFIG_PLUGIN_PROPERTY];
|
|
36
|
+
if (routeRootConfig) return routeRootConfig;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
28
40
|
async function loadVinextPrerenderConfigFromViteConfig(vite, root) {
|
|
29
41
|
return findVinextPrerenderConfigInPlugins((await vite.loadConfigFromFile({
|
|
30
42
|
command: "build",
|
|
31
43
|
mode: "production"
|
|
32
44
|
}, void 0, root))?.config.plugins);
|
|
33
45
|
}
|
|
46
|
+
async function loadVinextRouteRootConfigFromViteConfig(vite, root) {
|
|
47
|
+
return findVinextRouteRootConfigInPlugins((await vite.loadConfigFromFile({
|
|
48
|
+
command: "build",
|
|
49
|
+
mode: "production"
|
|
50
|
+
}, void 0, root))?.config.plugins);
|
|
51
|
+
}
|
|
34
52
|
function resolveVinextPrerenderDecision(options) {
|
|
35
53
|
if (options.prerenderAllFlag) return {
|
|
36
54
|
routes: "*",
|
|
@@ -52,4 +70,4 @@ function formatVinextPrerenderLabel(decision) {
|
|
|
52
70
|
return "Pre-rendering all routes...";
|
|
53
71
|
}
|
|
54
72
|
//#endregion
|
|
55
|
-
export { VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY, findVinextPrerenderConfigInPlugins, formatVinextPrerenderLabel, loadVinextPrerenderConfigFromViteConfig, normalizeVinextPrerenderConfig, resolveVinextPrerenderDecision };
|
|
73
|
+
export { VINEXT_CACHE_CONFIG_PLUGIN_PROPERTY, VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY, VINEXT_ROUTE_ROOT_CONFIG_PLUGIN_PROPERTY, findVinextCacheConfigInPlugins, findVinextPrerenderConfigInPlugins, findVinextRouteRootConfigInPlugins, formatVinextPrerenderLabel, loadVinextCacheConfigFromViteConfig, loadVinextPrerenderConfigFromViteConfig, loadVinextRouteRootConfigFromViteConfig, normalizeVinextPrerenderConfig, resolveVinextPrerenderDecision };
|
|
@@ -143,7 +143,11 @@ function loadTsconfigResolutionForRoot(projectRoot) {
|
|
|
143
143
|
for (const name of TSCONFIG_FILES) {
|
|
144
144
|
const candidate = path.join(projectRoot, name);
|
|
145
145
|
if (!fs.existsSync(candidate)) continue;
|
|
146
|
-
|
|
146
|
+
const resolution = loadResolutionFromTsconfigFile(candidate, /* @__PURE__ */ new Set());
|
|
147
|
+
return {
|
|
148
|
+
aliases: Object.fromEntries(Object.entries(resolution.aliases).sort((a, b) => b[0].length - a[0].length)),
|
|
149
|
+
baseUrl: resolution.baseUrl
|
|
150
|
+
};
|
|
147
151
|
}
|
|
148
152
|
return emptyResolution();
|
|
149
153
|
}
|
|
@@ -47,12 +47,16 @@ function toDocumentOnlyAppRoute(route) {
|
|
|
47
47
|
isDynamic: route.isDynamic
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
+
function requiresDynamicNavigationRequest(route) {
|
|
51
|
+
return route.isDynamic && route.parallelSlots.length > 0;
|
|
52
|
+
}
|
|
50
53
|
/** Project an `AppRoute` down to the public `VinextLinkPrefetchRoute` shape. */
|
|
51
54
|
function toLinkPrefetchRoute(route) {
|
|
52
55
|
return {
|
|
53
56
|
canPrefetchLoadingShell: route.loadingPath !== null,
|
|
54
57
|
patternParts: [...route.patternParts],
|
|
55
|
-
isDynamic: route.isDynamic
|
|
58
|
+
isDynamic: route.isDynamic,
|
|
59
|
+
...requiresDynamicNavigationRequest(route) ? { requiresDynamicNavigationRequest: true } : {}
|
|
56
60
|
};
|
|
57
61
|
}
|
|
58
62
|
function buildRouteManifestExpression(routeManifest) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite } from "../config/next-config.js";
|
|
1
|
+
import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite, PrefetchInliningConfig } from "../config/next-config.js";
|
|
2
2
|
import { AppRoute } from "../routing/app-route-graph.js";
|
|
3
3
|
import { MetadataFileRoute } from "../server/metadata-routes.js";
|
|
4
4
|
import { ImageConfig } from "../server/image-optimization.js";
|
|
@@ -45,7 +45,8 @@ type AppRouterConfig = {
|
|
|
45
45
|
cacheMaxMemorySize?: number; /** Inline app CSS into production HTML (from experimental.inlineCss). */
|
|
46
46
|
inlineCss?: boolean; /** Enable standalone route-miss 404 handling (from experimental.globalNotFound). */
|
|
47
47
|
globalNotFound?: boolean; /** Enables Next.js Cache Components semantics for App Router document HTML. */
|
|
48
|
-
cacheComponents?: boolean; /**
|
|
48
|
+
cacheComponents?: boolean; /** Resolved `experimental.prefetchInlining` thresholds. */
|
|
49
|
+
prefetchInlining?: PrefetchInliningConfig; /** Whether the RSC build discovered any server references. Defaults to true. */
|
|
49
50
|
hasServerActions?: boolean; /** Internationalization routing config for middleware matcher locale handling. */
|
|
50
51
|
i18n?: NextI18nConfig | null;
|
|
51
52
|
imageConfig?: ImageConfig;
|
|
@@ -78,6 +78,7 @@ function generateRscEntry(appDir, routes, middlewarePath, metadataRoutes, global
|
|
|
78
78
|
const cacheMaxMemorySize = config?.cacheMaxMemorySize;
|
|
79
79
|
const inlineCss = config?.inlineCss === true;
|
|
80
80
|
const cacheComponents = config?.cacheComponents === true;
|
|
81
|
+
const prefetchInlining = config?.prefetchInlining ?? false;
|
|
81
82
|
const hasServerActions = config?.hasServerActions !== false;
|
|
82
83
|
const i18nConfig = config?.i18n ?? null;
|
|
83
84
|
const hasPagesDir = config?.hasPagesDir ?? false;
|
|
@@ -493,6 +494,7 @@ export default createAppRscHandler({
|
|
|
493
494
|
basePath: __basePath,
|
|
494
495
|
buildId: process.env.__VINEXT_BUILD_ID ?? null,
|
|
495
496
|
ensureRouteLoaded: __ensureRouteLoaded,
|
|
497
|
+
prefetchInlining: ${JSON.stringify(prefetchInlining)},
|
|
496
498
|
clearRequestContext() {
|
|
497
499
|
__clearRequestContext();
|
|
498
500
|
},
|
|
@@ -527,6 +529,7 @@ export default createAppRscHandler({
|
|
|
527
529
|
staticParamsValidationParams,
|
|
528
530
|
rootParams,
|
|
529
531
|
request,
|
|
532
|
+
renderedPathAndSearch,
|
|
530
533
|
route,
|
|
531
534
|
scriptNonce,
|
|
532
535
|
searchParams,
|
|
@@ -693,6 +696,7 @@ export default createAppRscHandler({
|
|
|
693
696
|
prerenderToReadableStream,
|
|
694
697
|
request,
|
|
695
698
|
revalidateSeconds: __segmentConfig.revalidateSeconds,
|
|
699
|
+
renderedPathAndSearch,
|
|
696
700
|
resolveRouteFetchCacheMode(targetRoute) {
|
|
697
701
|
return __resolveRouteFetchCacheMode(targetRoute);
|
|
698
702
|
},
|
|
@@ -57,7 +57,10 @@ async function generateClientEntry(pagesDir, nextConfig, fileMatcher, options =
|
|
|
57
57
|
return ` ${JSON.stringify(nextFormatPattern)}: () => import(${JSON.stringify(absPath)})`;
|
|
58
58
|
});
|
|
59
59
|
const appFileBase = appFilePath ? normalizePathSeparators(appFilePath) : void 0;
|
|
60
|
-
|
|
60
|
+
const userInstrumentationImport = instrumentationClientPath ? `import ${JSON.stringify(normalizePathSeparators(instrumentationClientPath))};\n` : "";
|
|
61
|
+
const reactPreambleImport = options.reactPreamble === false ? "" : "import \"@vitejs/plugin-react/preamble\";\n";
|
|
62
|
+
const reactStrictModeEnabled = nextConfig.reactStrictMode === true;
|
|
63
|
+
return `${userInstrumentationImport}${reactPreambleImport}
|
|
61
64
|
import "vinext/instrumentation-client";
|
|
62
65
|
import React from "react";
|
|
63
66
|
import { hydrateRoot } from "react-dom/client";
|
|
@@ -89,6 +92,9 @@ const appLoader = undefined;
|
|
|
89
92
|
// can iterate in order and trust the first match.
|
|
90
93
|
window.__VINEXT_PAGE_LOADERS__ = pageLoaders;
|
|
91
94
|
window.__VINEXT_PAGE_PATTERNS__ = Object.keys(pageLoaders);
|
|
95
|
+
// reactStrictMode flag — read by wrapWithRouterContext (next/router) so the
|
|
96
|
+
// <React.StrictMode> wrap is applied on initial hydration and every navigation.
|
|
97
|
+
window.__VINEXT_REACT_STRICT_MODE__ = ${JSON.stringify(reactStrictModeEnabled)};
|
|
92
98
|
window.__VINEXT_PAGES_SSG_PATTERNS__ = ${JSON.stringify(pagesSsgPatterns)};
|
|
93
99
|
window.__VINEXT_PAGES_SSP_PATTERNS__ = ${JSON.stringify(pagesSspPatterns)};
|
|
94
100
|
window.__VINEXT_MIDDLEWARE_MATCHER__ = ${JSON.stringify(options.middlewareMatcher)};
|
|
@@ -186,6 +192,9 @@ async function hydrate() {
|
|
|
186
192
|
});
|
|
187
193
|
|
|
188
194
|
// Wrap with RouterContext.Provider so next/router and next/compat/router work during hydration.
|
|
195
|
+
// When reactStrictMode is enabled, wrapWithRouterContext also wraps the tree
|
|
196
|
+
// in <React.StrictMode> (see next/router) — applied here and on every
|
|
197
|
+
// navigation render, matching Next.js.
|
|
189
198
|
element = wrapWithRouterContext(element, resolveHydrationCommit);
|
|
190
199
|
|
|
191
200
|
const container = document.getElementById("__next");
|
|
@@ -204,9 +213,11 @@ async function hydrate() {
|
|
|
204
213
|
window.__NEXT_HYDRATED_CB?.();
|
|
205
214
|
|
|
206
215
|
if (nextData.isFallback) {
|
|
216
|
+
const currentUrl = window.location.pathname + window.location.search + window.location.hash;
|
|
217
|
+
const routeUrl = nextData.__vinext?.routeUrl;
|
|
207
218
|
await Router.replace(
|
|
208
|
-
|
|
209
|
-
undefined,
|
|
219
|
+
routeUrl || currentUrl,
|
|
220
|
+
routeUrl ? currentUrl : undefined,
|
|
210
221
|
{ _h: 1, scroll: false },
|
|
211
222
|
);
|
|
212
223
|
}
|
|
@@ -4,6 +4,8 @@ import { apiRouter, pagesRouter } from "../routing/pages-router.js";
|
|
|
4
4
|
import { resolveEntryPath } from "./runtime-entry-module.js";
|
|
5
5
|
import { isProxyFile } from "../server/middleware.js";
|
|
6
6
|
import "./pages-entry-helpers.js";
|
|
7
|
+
import { hasExportedName } from "../build/report.js";
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
7
9
|
//#region src/entries/pages-server-entry.ts
|
|
8
10
|
/**
|
|
9
11
|
* Pages Router server entry generator.
|
|
@@ -24,6 +26,12 @@ const _pagesApiRoutePath = resolveEntryPath("../server/pages-api-route.js", impo
|
|
|
24
26
|
const _serverGlobalsPath = resolveEntryPath("../server/server-globals.js", import.meta.url);
|
|
25
27
|
const _queryUtilsPath = resolveEntryPath("../utils/query.js", import.meta.url);
|
|
26
28
|
const _pagesPageHandlerPath = resolveEntryPath("../server/pages-page-handler.js", import.meta.url);
|
|
29
|
+
async function getPagesDataKind(filePath) {
|
|
30
|
+
const source = await readFile(filePath, "utf8");
|
|
31
|
+
if (hasExportedName(source, "getStaticProps")) return "static";
|
|
32
|
+
if (hasExportedName(source, "getServerSideProps")) return "server";
|
|
33
|
+
return "none";
|
|
34
|
+
}
|
|
27
35
|
/**
|
|
28
36
|
* Generate the virtual SSR server entry module.
|
|
29
37
|
* This is the entry point for `vite build --ssr`.
|
|
@@ -39,10 +47,11 @@ async function generateServerEntry(pagesDir, nextConfig, fileMatcher, middleware
|
|
|
39
47
|
const absPath = normalizePathSeparators(r.filePath);
|
|
40
48
|
return `import * as api_${i} from ${JSON.stringify(absPath)};`;
|
|
41
49
|
});
|
|
42
|
-
const pageRouteEntries = pageRoutes.map((r, i) => {
|
|
50
|
+
const pageRouteEntries = await Promise.all(pageRoutes.map(async (r, i) => {
|
|
43
51
|
const absPath = normalizePathSeparators(r.filePath);
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
const dataKind = await getPagesDataKind(r.filePath);
|
|
53
|
+
return ` { pattern: ${JSON.stringify(r.pattern)}, patternParts: ${JSON.stringify(r.patternParts)}, isDynamic: ${r.isDynamic}, params: ${JSON.stringify(r.params)}, module: page_${i}, filePath: ${JSON.stringify(absPath)}, dataKind: ${JSON.stringify(dataKind)} }`;
|
|
54
|
+
}));
|
|
46
55
|
const apiRouteEntries = apiRoutes.map((r, i) => ` { pattern: ${JSON.stringify(r.pattern)}, patternParts: ${JSON.stringify(r.patternParts)}, isDynamic: ${r.isDynamic}, params: ${JSON.stringify(r.params)}, module: api_${i} }`);
|
|
47
56
|
const appFilePath = findFileWithExts(pagesDir, "_app", fileMatcher);
|
|
48
57
|
const docFilePath = findFileWithExts(pagesDir, "_document", fileMatcher);
|
|
@@ -164,7 +173,12 @@ const i18nConfig = ${i18nConfigJson};
|
|
|
164
173
|
// to load next.config.js at runtime.
|
|
165
174
|
export const buildId = ${buildIdJson};
|
|
166
175
|
export function normalizeDataRequest(request) {
|
|
167
|
-
return __normalizePagesDataRequest(
|
|
176
|
+
return __normalizePagesDataRequest(
|
|
177
|
+
request,
|
|
178
|
+
buildId,
|
|
179
|
+
vinextConfig.basePath,
|
|
180
|
+
hasMiddleware && vinextConfig.trailingSlash,
|
|
181
|
+
);
|
|
168
182
|
}
|
|
169
183
|
export const hasMiddleware = ${JSON.stringify(Boolean(middlewarePath))};
|
|
170
184
|
|
|
@@ -44,6 +44,7 @@ function generateImageAdaptersModule(images) {
|
|
|
44
44
|
"let __vinextImageOptimizerRegistered = false;",
|
|
45
45
|
"",
|
|
46
46
|
"export function registerConfiguredImageOptimizer(env) {",
|
|
47
|
+
" if (typeof process !== 'undefined' && process.env?.__VINEXT_PRERENDER_PATH_DISCOVERY === '1') return;",
|
|
47
48
|
" if (__vinextImageOptimizerRegistered) return;",
|
|
48
49
|
" __vinextImageOptimizerRegistered = true;",
|
|
49
50
|
" try {",
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NextConfig, NextConfigInput } from "./config/next-config.js";
|
|
2
|
-
import { AppStaticExportOptions, StaticExportOptions, StaticExportResult, staticExportApp, staticExportPages } from "./build/static-export.js";
|
|
3
2
|
import { VinextCacheConfig } from "./cache/cache-adapters-virtual.js";
|
|
4
3
|
import { VinextPrerenderConfig } from "./config/prerender.js";
|
|
4
|
+
import { AppStaticExportOptions, StaticExportOptions, StaticExportResult, staticExportApp, staticExportPages } from "./build/static-export.js";
|
|
5
5
|
import { VinextImageConfig } from "./image/image-adapters-virtual.js";
|
|
6
6
|
import { PluginOption } from "vite";
|
|
7
7
|
import { Options } from "@vitejs/plugin-react";
|