@vercel/next 4.0.0 → 4.0.2
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/index.js +1052 -763
- package/dist/server-build.js +96 -7
- package/dist/utils.js +29 -23
- package/package.json +3 -3
package/dist/server-build.js
CHANGED
@@ -39,11 +39,14 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, functionsConfi
|
|
39
39
|
inversedAppPathManifest[appPathRoutesManifest[ogRoute]] = ogRoute;
|
40
40
|
}
|
41
41
|
}
|
42
|
+
const APP_PREFETCH_SUFFIX = '.prefetch.rsc';
|
43
|
+
let appRscPrefetches = {};
|
42
44
|
let appBuildTraces = {};
|
43
45
|
let appDir = null;
|
44
46
|
if (appPathRoutesManifest) {
|
45
47
|
appDir = path_1.default.join(pagesDir, '../app');
|
46
48
|
appBuildTraces = await (0, build_utils_1.glob)('**/*.js.nft.json', appDir);
|
49
|
+
appRscPrefetches = await (0, build_utils_1.glob)(`**/*${APP_PREFETCH_SUFFIX}`, appDir);
|
47
50
|
}
|
48
51
|
const isCorrectNotFoundRoutes = semver_1.default.gte(nextVersion, CORRECT_NOT_FOUND_ROUTES_VERSION);
|
49
52
|
const isCorrectMiddlewareOrder = semver_1.default.gte(nextVersion, CORRECT_MIDDLEWARE_ORDER_VERSION);
|
@@ -203,10 +206,17 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, functionsConfi
|
|
203
206
|
// for notFound GS(S)P support
|
204
207
|
if (i18n) {
|
205
208
|
for (const locale of i18n.locales) {
|
206
|
-
|
207
|
-
|
209
|
+
let static404File = staticPages[path_1.default.posix.join(entryDirectory, locale, '/404')];
|
210
|
+
if (!static404File) {
|
211
|
+
static404File = new build_utils_1.FileFsRef({
|
208
212
|
fsPath: path_1.default.join(pagesDir, locale, '/404.html'),
|
209
213
|
});
|
214
|
+
if (!fs_extra_1.default.existsSync(static404File.fsPath)) {
|
215
|
+
static404File = new build_utils_1.FileFsRef({
|
216
|
+
fsPath: path_1.default.join(pagesDir, '/404.html'),
|
217
|
+
});
|
218
|
+
}
|
219
|
+
}
|
210
220
|
requiredFiles[path_1.default.relative(baseDir, static404File.fsPath)] =
|
211
221
|
static404File;
|
212
222
|
}
|
@@ -619,7 +629,25 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, functionsConfi
|
|
619
629
|
});
|
620
630
|
const isNextDataServerResolving = middleware.staticRoutes.length > 0 &&
|
621
631
|
semver_1.default.gte(nextVersion, NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION);
|
622
|
-
const dynamicRoutes = await (0, utils_1.getDynamicRoutes)(entryPath, entryDirectory, dynamicPages, false, routesManifest, omittedPrerenderRoutes, canUsePreviewMode, prerenderManifest.bypassToken || '', true, middleware.dynamicRouteMap
|
632
|
+
const dynamicRoutes = await (0, utils_1.getDynamicRoutes)(entryPath, entryDirectory, dynamicPages, false, routesManifest, omittedPrerenderRoutes, canUsePreviewMode, prerenderManifest.bypassToken || '', true, middleware.dynamicRouteMap).then(arr => (0, utils_1.localizeDynamicRoutes)(arr, dynamicPrefix, entryDirectory, staticPages, prerenderManifest, routesManifest, true, isCorrectLocaleAPIRoutes, inversedAppPathManifest));
|
633
|
+
const pagesPlaceholderRscEntries = {};
|
634
|
+
if (appDir) {
|
635
|
+
// since we attempt to rewrite all paths to an .rsc variant,
|
636
|
+
// we need to create dummy rsc outputs for all pages entries
|
637
|
+
// this is so that an RSC request to a `pages` entry will match
|
638
|
+
// rather than falling back to a catchall `app` entry
|
639
|
+
// on the nextjs side, invalid RSC response payloads will correctly trigger an mpa navigation
|
640
|
+
const pagesManifest = path_1.default.join(entryPath, outputDirectory, `server/pages-manifest.json`);
|
641
|
+
const pagesData = await fs_extra_1.default.readJSON(pagesManifest);
|
642
|
+
const pagesEntries = Object.keys(pagesData);
|
643
|
+
for (const page of pagesEntries) {
|
644
|
+
const pathName = page.startsWith('/') ? page.slice(1) : page;
|
645
|
+
pagesPlaceholderRscEntries[`${pathName}.rsc`] = new build_utils_1.FileBlob({
|
646
|
+
data: '{}',
|
647
|
+
contentType: 'application/json',
|
648
|
+
});
|
649
|
+
}
|
650
|
+
}
|
623
651
|
const { staticFiles, publicDirectoryFiles, staticDirectoryFiles } = await (0, utils_1.getStaticFiles)(entryPath, entryDirectory, outputDirectory);
|
624
652
|
const normalizeNextDataRoute = (isOverride = false) => {
|
625
653
|
return isNextDataServerResolving
|
@@ -705,7 +733,7 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, functionsConfi
|
|
705
733
|
if (ogRoute.endsWith('/route')) {
|
706
734
|
continue;
|
707
735
|
}
|
708
|
-
route = path_1.default.posix.join('./', entryDirectory, route === '/' ? '/index' : route);
|
736
|
+
route = (0, utils_1.normalizeIndexOutput)(path_1.default.posix.join('./', entryDirectory, route === '/' ? '/index' : route), true);
|
709
737
|
if (lambdas[route]) {
|
710
738
|
lambdas[`${route}.rsc`] = lambdas[route];
|
711
739
|
}
|
@@ -715,6 +743,7 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, functionsConfi
|
|
715
743
|
}
|
716
744
|
}
|
717
745
|
const rscHeader = routesManifest.rsc?.header?.toLowerCase() || '__rsc__';
|
746
|
+
const rscPrefetchHeader = routesManifest.rsc?.prefetchHeader?.toLowerCase();
|
718
747
|
const rscVaryHeader = routesManifest?.rsc?.varyHeader ||
|
719
748
|
'RSC, Next-Router-State-Tree, Next-Router-Prefetch';
|
720
749
|
const appNotFoundPath = path_1.default.posix.join('.', entryDirectory, '_not-found');
|
@@ -724,6 +753,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, functionsConfi
|
|
724
753
|
output: {
|
725
754
|
...publicDirectoryFiles,
|
726
755
|
...lambdas,
|
756
|
+
...appRscPrefetches,
|
757
|
+
...pagesPlaceholderRscEntries,
|
727
758
|
// Prerenders may override Lambdas -- this is an intentional behavior.
|
728
759
|
...prerenders,
|
729
760
|
...staticPages,
|
@@ -905,6 +936,36 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, functionsConfi
|
|
905
936
|
...(!isCorrectMiddlewareOrder ? middleware.staticRoutes : []),
|
906
937
|
...(appDir
|
907
938
|
? [
|
939
|
+
...(rscPrefetchHeader
|
940
|
+
? [
|
941
|
+
{
|
942
|
+
src: `^${path_1.default.posix.join('/', entryDirectory, '/')}`,
|
943
|
+
has: [
|
944
|
+
{
|
945
|
+
type: 'header',
|
946
|
+
key: rscPrefetchHeader,
|
947
|
+
},
|
948
|
+
],
|
949
|
+
dest: path_1.default.posix.join('/', entryDirectory, '/index.prefetch.rsc'),
|
950
|
+
headers: { vary: rscVaryHeader },
|
951
|
+
continue: true,
|
952
|
+
override: true,
|
953
|
+
},
|
954
|
+
{
|
955
|
+
src: `^${path_1.default.posix.join('/', entryDirectory, '/((?!.+\\.rsc).+?)(?:/)?$')}`,
|
956
|
+
has: [
|
957
|
+
{
|
958
|
+
type: 'header',
|
959
|
+
key: rscPrefetchHeader,
|
960
|
+
},
|
961
|
+
],
|
962
|
+
dest: path_1.default.posix.join('/', entryDirectory, `/$1${APP_PREFETCH_SUFFIX}`),
|
963
|
+
headers: { vary: rscVaryHeader },
|
964
|
+
continue: true,
|
965
|
+
override: true,
|
966
|
+
},
|
967
|
+
]
|
968
|
+
: []),
|
908
969
|
{
|
909
970
|
src: `^${path_1.default.posix.join('/', entryDirectory, '/')}`,
|
910
971
|
has: [
|
@@ -960,17 +1021,45 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, functionsConfi
|
|
960
1021
|
},
|
961
1022
|
]
|
962
1023
|
: []),
|
1024
|
+
...(rscPrefetchHeader
|
1025
|
+
? [
|
1026
|
+
{
|
1027
|
+
src: path_1.default.posix.join('/', entryDirectory, `/index${APP_PREFETCH_SUFFIX}`),
|
1028
|
+
dest: path_1.default.posix.join('/', entryDirectory, '/index.rsc'),
|
1029
|
+
has: [
|
1030
|
+
{
|
1031
|
+
type: 'header',
|
1032
|
+
key: rscPrefetchHeader,
|
1033
|
+
},
|
1034
|
+
],
|
1035
|
+
continue: true,
|
1036
|
+
override: true,
|
1037
|
+
},
|
1038
|
+
{
|
1039
|
+
src: `^${path_1.default.posix.join('/', entryDirectory, `/(.+?)${APP_PREFETCH_SUFFIX}(?:/)?$`)}`,
|
1040
|
+
dest: path_1.default.posix.join('/', entryDirectory, '/$1.rsc'),
|
1041
|
+
has: [
|
1042
|
+
{
|
1043
|
+
type: 'header',
|
1044
|
+
key: rscPrefetchHeader,
|
1045
|
+
},
|
1046
|
+
],
|
1047
|
+
continue: true,
|
1048
|
+
override: true,
|
1049
|
+
},
|
1050
|
+
]
|
1051
|
+
: []),
|
963
1052
|
// These need to come before handle: miss or else they are grouped
|
964
1053
|
// with that routing section
|
965
1054
|
...afterFilesRewrites,
|
966
|
-
// make sure 404 page is used when a directory is matched without
|
967
|
-
// an index page
|
968
1055
|
{ handle: 'resource' },
|
969
1056
|
...fallbackRewrites,
|
1057
|
+
// make sure 404 page is used when a directory is matched without
|
1058
|
+
// an index page
|
970
1059
|
{ src: path_1.default.posix.join('/', entryDirectory, '.*'), status: 404 },
|
1060
|
+
{ handle: 'miss' },
|
971
1061
|
// We need to make sure to 404 for /_next after handle: miss since
|
972
1062
|
// handle: miss is called before rewrites and to prevent rewriting /_next
|
973
|
-
{ handle: 'miss' },
|
974
1063
|
{
|
975
1064
|
src: path_1.default.posix.join('/', entryDirectory, '_next/static/(?:[^/]+/pages|pages|chunks|runtime|css|image|media)/.+'),
|
976
1065
|
status: 404,
|
package/dist/utils.js
CHANGED
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
27
27
|
};
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
29
|
-
exports.isApiPage = exports.getOperationType = exports.upgradeMiddlewareManifest = exports.getMiddlewareManifest = exports.getFunctionsConfigManifest = exports.getMiddlewareBundle = exports.getSourceFilePathFromPage = exports.isDynamicRoute = exports.normalizePage = exports.getImagesConfig = exports.getNextConfig = exports.normalizePackageJson = exports.validateEntrypoint = exports.excludeFiles = exports.getPrivateOutputs = exports.updateRouteSrc = exports.getNextServerPath = exports.normalizeIndexOutput = exports.getStaticFiles = exports.onPrerenderRoute = exports.onPrerenderRouteInitial = exports.detectLambdaLimitExceeding = exports.outputFunctionFileSizeInfo = exports.getPageLambdaGroups = exports.MAX_UNCOMPRESSED_LAMBDA_SIZE = exports.addLocaleOrDefault = exports.normalizeLocalePath = exports.getPrerenderManifest = exports.getRequiredServerFilesManifest = exports.getExportStatus = exports.getExportIntent = exports.createLambdaFromPseudoLayers = exports.createPseudoLayer = exports.ExperimentalTraceVersion = exports.collectTracedFiles = exports.getFilesMapFromReasons = exports.filterStaticPages = exports.getImagesManifest = exports.localizeDynamicRoutes = exports.getDynamicRoutes = exports.getRoutesManifest = exports.prettyBytes = exports.MIB = exports.KIB = void 0;
|
29
|
+
exports.isApiPage = exports.getOperationType = exports.upgradeMiddlewareManifest = exports.getMiddlewareManifest = exports.getFunctionsConfigManifest = exports.getMiddlewareBundle = exports.normalizeEdgeFunctionPath = exports.getSourceFilePathFromPage = exports.isDynamicRoute = exports.normalizePage = exports.getImagesConfig = exports.getNextConfig = exports.normalizePackageJson = exports.validateEntrypoint = exports.excludeFiles = exports.getPrivateOutputs = exports.updateRouteSrc = exports.getNextServerPath = exports.normalizeIndexOutput = exports.getStaticFiles = exports.onPrerenderRoute = exports.onPrerenderRouteInitial = exports.detectLambdaLimitExceeding = exports.outputFunctionFileSizeInfo = exports.getPageLambdaGroups = exports.MAX_UNCOMPRESSED_LAMBDA_SIZE = exports.addLocaleOrDefault = exports.normalizeLocalePath = exports.getPrerenderManifest = exports.getRequiredServerFilesManifest = exports.getExportStatus = exports.getExportIntent = exports.createLambdaFromPseudoLayers = exports.createPseudoLayer = exports.ExperimentalTraceVersion = exports.collectTracedFiles = exports.getFilesMapFromReasons = exports.filterStaticPages = exports.getImagesManifest = exports.localizeDynamicRoutes = exports.getDynamicRoutes = exports.getRoutesManifest = exports.prettyBytes = exports.MIB = exports.KIB = void 0;
|
30
30
|
const build_utils_1 = require("@vercel/build-utils");
|
31
31
|
const async_sema_1 = require("async-sema");
|
32
32
|
const buffer_crc32_1 = __importDefault(require("buffer-crc32"));
|
@@ -194,7 +194,7 @@ async function getRoutesManifest(entryPath, outputDirectory, nextVersion) {
|
|
194
194
|
return routesManifest;
|
195
195
|
}
|
196
196
|
exports.getRoutesManifest = getRoutesManifest;
|
197
|
-
async function getDynamicRoutes(entryPath, entryDirectory, dynamicPages, isDev, routesManifest, omittedRoutes, canUsePreviewMode, bypassToken, isServerMode, dynamicMiddlewareRouteMap
|
197
|
+
async function getDynamicRoutes(entryPath, entryDirectory, dynamicPages, isDev, routesManifest, omittedRoutes, canUsePreviewMode, bypassToken, isServerMode, dynamicMiddlewareRouteMap) {
|
198
198
|
if (routesManifest) {
|
199
199
|
switch (routesManifest.version) {
|
200
200
|
case 1:
|
@@ -253,13 +253,11 @@ async function getDynamicRoutes(entryPath, entryDirectory, dynamicPages, isDev,
|
|
253
253
|
},
|
254
254
|
];
|
255
255
|
}
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
});
|
262
|
-
}
|
256
|
+
routes.push({
|
257
|
+
...route,
|
258
|
+
src: route.src.replace(new RegExp((0, escape_string_regexp_1.default)('(?:/)?$')), '(?:\\.rsc)(?:/)?$'),
|
259
|
+
dest: route.dest?.replace(/($|\?)/, '.rsc$1'),
|
260
|
+
});
|
263
261
|
routes.push(route);
|
264
262
|
continue;
|
265
263
|
}
|
@@ -1249,6 +1247,9 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
|
|
1249
1247
|
? dataRoute
|
1250
1248
|
: routeFileNoExt + '.json'}`),
|
1251
1249
|
});
|
1250
|
+
if (isOmittedOrNotFound) {
|
1251
|
+
initialStatus = 404;
|
1252
|
+
}
|
1252
1253
|
if (isAppPathRoute) {
|
1253
1254
|
// for literal index routes we need to append an additional /index
|
1254
1255
|
// due to the proxy's normalizing for /index routes
|
@@ -1500,7 +1501,7 @@ async function getStaticFiles(entryPath, entryDirectory, outputDirectory) {
|
|
1500
1501
|
}
|
1501
1502
|
exports.getStaticFiles = getStaticFiles;
|
1502
1503
|
function normalizeIndexOutput(outputName, isServerMode) {
|
1503
|
-
if (outputName !== '/index' && isServerMode) {
|
1504
|
+
if (outputName !== 'index' && outputName !== '/index' && isServerMode) {
|
1504
1505
|
return outputName.replace(/\/index$/, '');
|
1505
1506
|
}
|
1506
1507
|
return outputName;
|
@@ -1594,6 +1595,21 @@ function normalizeRegions(regions) {
|
|
1594
1595
|
}
|
1595
1596
|
return newRegions;
|
1596
1597
|
}
|
1598
|
+
function normalizeEdgeFunctionPath(shortPath, appPathRoutesManifest) {
|
1599
|
+
if (shortPath.startsWith('app/') &&
|
1600
|
+
(shortPath.endsWith('/page') ||
|
1601
|
+
shortPath.endsWith('/route') ||
|
1602
|
+
shortPath === 'app/_not-found')) {
|
1603
|
+
const ogRoute = shortPath.replace(/^app\//, '/');
|
1604
|
+
shortPath = (appPathRoutesManifest[ogRoute] ||
|
1605
|
+
shortPath.replace(/(^|\/)(page|route)$/, '')).replace(/^\//, '');
|
1606
|
+
if (!shortPath || shortPath === '/') {
|
1607
|
+
shortPath = 'index';
|
1608
|
+
}
|
1609
|
+
}
|
1610
|
+
return shortPath;
|
1611
|
+
}
|
1612
|
+
exports.normalizeEdgeFunctionPath = normalizeEdgeFunctionPath;
|
1597
1613
|
async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest, isCorrectMiddlewareOrder, prerenderBypassToken, nextVersion, appPathRoutesManifest, }) {
|
1598
1614
|
const middlewareManifest = await getMiddlewareManifest(entryPath, outputDirectory);
|
1599
1615
|
const sortedFunctions = [
|
@@ -1710,21 +1726,11 @@ async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest,
|
|
1710
1726
|
if (shortPath.startsWith('pages/')) {
|
1711
1727
|
shortPath = shortPath.replace(/^pages\//, '');
|
1712
1728
|
}
|
1713
|
-
else
|
1714
|
-
(shortPath
|
1715
|
-
shortPath.endsWith('/route') ||
|
1716
|
-
shortPath === 'app/_not-found')) {
|
1717
|
-
const ogRoute = shortPath.replace(/^app\//, '/');
|
1718
|
-
shortPath = (appPathRoutesManifest[ogRoute] ||
|
1719
|
-
shortPath.replace(/(^|\/)(page|route)$/, '')).replace(/^\//, '');
|
1720
|
-
if (!shortPath || shortPath === '/') {
|
1721
|
-
shortPath = 'index';
|
1722
|
-
}
|
1729
|
+
else {
|
1730
|
+
shortPath = normalizeEdgeFunctionPath(shortPath, appPathRoutesManifest);
|
1723
1731
|
}
|
1724
1732
|
if (routesManifest?.basePath) {
|
1725
|
-
shortPath = path_1.default.posix
|
1726
|
-
.join(routesManifest.basePath, shortPath)
|
1727
|
-
.replace(/^\//, '');
|
1733
|
+
shortPath = normalizeIndexOutput(path_1.default.posix.join('./', routesManifest?.basePath, shortPath.replace(/^\//, '')), true);
|
1728
1734
|
}
|
1729
1735
|
worker.edgeFunction.name = shortPath;
|
1730
1736
|
source.edgeFunctions[shortPath] = worker.edgeFunction;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vercel/next",
|
3
|
-
"version": "4.0.
|
3
|
+
"version": "4.0.2",
|
4
4
|
"license": "Apache-2.0",
|
5
5
|
"main": "./dist/index",
|
6
6
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
@@ -26,7 +26,7 @@
|
|
26
26
|
"@types/semver": "6.0.0",
|
27
27
|
"@types/text-table": "0.2.1",
|
28
28
|
"@types/webpack-sources": "3.2.0",
|
29
|
-
"@vercel/build-utils": "7.
|
29
|
+
"@vercel/build-utils": "7.1.1",
|
30
30
|
"@vercel/nft": "0.22.5",
|
31
31
|
"@vercel/routing-utils": "3.0.0",
|
32
32
|
"async-sema": "3.0.1",
|
@@ -45,7 +45,7 @@
|
|
45
45
|
"ndjson": "2.0.0",
|
46
46
|
"pretty-bytes": "5.3.0",
|
47
47
|
"resolve-from": "5.0.0",
|
48
|
-
"semver": "6.
|
48
|
+
"semver": "6.3.1",
|
49
49
|
"set-cookie-parser": "2.4.6",
|
50
50
|
"source-map": "0.7.3",
|
51
51
|
"test-listen": "1.1.0",
|