Revert "[next] Reland add .action handling for dynamic routes" (#11509)

Reverts vercel/vercel#11487.

This feature will be relanded behind a feature flag.
This commit is contained in:
Zack Tanner
2024-04-29 08:26:15 -07:00
committed by GitHub
parent 863199aa0a
commit 5b79603378
8 changed files with 31 additions and 143 deletions

View File

@@ -0,0 +1,5 @@
---
"@vercel/next": patch
---
[next]: Revert .action handling for dynamic routes

View File

@@ -1928,7 +1928,6 @@ export const build: BuildV2 = async ({
bypassToken: prerenderManifest.bypassToken || '', bypassToken: prerenderManifest.bypassToken || '',
isServerMode, isServerMode,
experimentalPPRRoutes, experimentalPPRRoutes,
hasActionOutputSupport: false,
}).then(arr => }).then(arr =>
localizeDynamicRoutes( localizeDynamicRoutes(
arr, arr,
@@ -1959,7 +1958,6 @@ export const build: BuildV2 = async ({
bypassToken: prerenderManifest.bypassToken || '', bypassToken: prerenderManifest.bypassToken || '',
isServerMode, isServerMode,
experimentalPPRRoutes, experimentalPPRRoutes,
hasActionOutputSupport: false,
}).then(arr => }).then(arr =>
arr.map(route => { arr.map(route => {
route.src = route.src.replace('^', `^${dynamicPrefix}`); route.src = route.src.replace('^', `^${dynamicPrefix}`);

View File

@@ -51,7 +51,6 @@ import {
normalizePrefetches, normalizePrefetches,
CreateLambdaFromPseudoLayersOptions, CreateLambdaFromPseudoLayersOptions,
getPostponeResumePathname, getPostponeResumePathname,
LambdaGroup,
MAX_UNCOMPRESSED_LAMBDA_SIZE, MAX_UNCOMPRESSED_LAMBDA_SIZE,
} from './utils'; } from './utils';
import { import {
@@ -69,7 +68,6 @@ const CORRECT_NOT_FOUND_ROUTES_VERSION = 'v12.0.1';
const CORRECT_MIDDLEWARE_ORDER_VERSION = 'v12.1.7-canary.29'; const CORRECT_MIDDLEWARE_ORDER_VERSION = 'v12.1.7-canary.29';
const NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION = 'v12.1.7-canary.33'; const NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION = 'v12.1.7-canary.33';
const EMPTY_ALLOW_QUERY_FOR_PRERENDERED_VERSION = 'v12.2.0'; const EMPTY_ALLOW_QUERY_FOR_PRERENDERED_VERSION = 'v12.2.0';
const ACTION_OUTPUT_SUPPORT_VERSION = 'v14.2.2';
const CORRECTED_MANIFESTS_VERSION = 'v12.2.0'; const CORRECTED_MANIFESTS_VERSION = 'v12.2.0';
// Ideally this should be in a Next.js manifest so we can change it in // Ideally this should be in a Next.js manifest so we can change it in
@@ -201,10 +199,6 @@ export async function serverBuild({
nextVersion, nextVersion,
EMPTY_ALLOW_QUERY_FOR_PRERENDERED_VERSION EMPTY_ALLOW_QUERY_FOR_PRERENDERED_VERSION
); );
const hasActionOutputSupport = semver.gte(
nextVersion,
ACTION_OUTPUT_SUPPORT_VERSION
);
const projectDir = requiredServerFilesManifest.relativeAppDir const projectDir = requiredServerFilesManifest.relativeAppDir
? path.join(baseDir, requiredServerFilesManifest.relativeAppDir) ? path.join(baseDir, requiredServerFilesManifest.relativeAppDir)
: requiredServerFilesManifest.appDir || entryPath; : requiredServerFilesManifest.appDir || entryPath;
@@ -932,23 +926,11 @@ export async function serverBuild({
inversedAppPathManifest, inversedAppPathManifest,
}); });
const appRouterStreamingActionLambdaGroups: LambdaGroup[] = [];
for (const group of appRouterLambdaGroups) { for (const group of appRouterLambdaGroups) {
if (!group.isPrerenders || group.isExperimentalPPR) { if (!group.isPrerenders || group.isExperimentalPPR) {
group.isStreaming = true; group.isStreaming = true;
} }
group.isAppRouter = true; group.isAppRouter = true;
// We create a streaming variant of the Prerender lambda group
// to support actions that are part of a Prerender
if (hasActionOutputSupport) {
appRouterStreamingActionLambdaGroups.push({
...group,
isActionLambda: true,
isStreaming: true,
});
}
} }
for (const group of appRouteHandlersLambdaGroups) { for (const group of appRouteHandlersLambdaGroups) {
@@ -1000,13 +982,6 @@ export async function serverBuild({
pseudoLayerBytes: group.pseudoLayerBytes, pseudoLayerBytes: group.pseudoLayerBytes,
uncompressedLayerBytes: group.pseudoLayerUncompressedBytes, uncompressedLayerBytes: group.pseudoLayerUncompressedBytes,
})), })),
appRouterStreamingPrerenderLambdaGroups:
appRouterStreamingActionLambdaGroups.map(group => ({
pages: group.pages,
isPrerender: group.isPrerenders,
pseudoLayerBytes: group.pseudoLayerBytes,
uncompressedLayerBytes: group.pseudoLayerUncompressedBytes,
})),
appRouteHandlersLambdaGroups: appRouteHandlersLambdaGroups.map( appRouteHandlersLambdaGroups: appRouteHandlersLambdaGroups.map(
group => ({ group => ({
pages: group.pages, pages: group.pages,
@@ -1024,7 +999,6 @@ export async function serverBuild({
const combinedGroups = [ const combinedGroups = [
...pageLambdaGroups, ...pageLambdaGroups,
...appRouterLambdaGroups, ...appRouterLambdaGroups,
...appRouterStreamingActionLambdaGroups,
...apiLambdaGroups, ...apiLambdaGroups,
...appRouteHandlersLambdaGroups, ...appRouteHandlersLambdaGroups,
]; ];
@@ -1234,11 +1208,6 @@ export async function serverBuild({
let outputName = path.posix.join(entryDirectory, pageName); let outputName = path.posix.join(entryDirectory, pageName);
if (group.isActionLambda) {
// give the streaming prerenders a .action suffix
outputName = `${outputName}.action`;
}
// If this is a PPR page, then we should prefix the output name. // If this is a PPR page, then we should prefix the output name.
if (isPPR) { if (isPPR) {
if (!revalidate) { if (!revalidate) {
@@ -1409,7 +1378,6 @@ export async function serverBuild({
isServerMode: true, isServerMode: true,
dynamicMiddlewareRouteMap: middleware.dynamicRouteMap, dynamicMiddlewareRouteMap: middleware.dynamicRouteMap,
experimentalPPRRoutes, experimentalPPRRoutes,
hasActionOutputSupport,
}).then(arr => }).then(arr =>
localizeDynamicRoutes( localizeDynamicRoutes(
arr, arr,
@@ -1937,72 +1905,7 @@ export async function serverBuild({
}, },
] ]
: []), : []),
...(hasActionOutputSupport
? [
// Create rewrites for streaming prerenders (.action routes)
// This contains separate rewrites for each possible "has" (action header, or content-type)
// Also includes separate handling for index routes which should match to /index.action.
// This follows the same pattern as the rewrites for .rsc files.
{
src: `^${path.posix.join('/', entryDirectory, '/')}`,
dest: path.posix.join('/', entryDirectory, '/index.action'),
has: [
{
type: 'header',
key: 'next-action',
},
],
continue: true,
override: true,
},
{
src: `^${path.posix.join('/', entryDirectory, '/')}`,
dest: path.posix.join('/', entryDirectory, '/index.action'),
has: [
{
type: 'header',
key: 'content-type',
value: 'multipart/form-data;.*',
},
],
continue: true,
override: true,
},
{
src: `^${path.posix.join(
'/',
entryDirectory,
'/((?!.+\\.action).+?)(?:/)?$'
)}`,
dest: path.posix.join('/', entryDirectory, '/$1.action'),
has: [
{
type: 'header',
key: 'next-action',
},
],
continue: true,
override: true,
},
{
src: `^${path.posix.join(
'/',
entryDirectory,
'/((?!.+\\.action).+?)(?:/)?$'
)}`,
dest: path.posix.join('/', entryDirectory, '/$1.action'),
has: [
{
type: 'header',
key: 'content-type',
value: 'multipart/form-data;.*',
},
],
continue: true,
override: true,
},
]
: []),
{ {
src: `^${path.posix.join('/', entryDirectory, '/')}`, src: `^${path.posix.join('/', entryDirectory, '/')}`,
has: [ has: [

View File

@@ -321,7 +321,6 @@ export async function getDynamicRoutes({
isServerMode, isServerMode,
dynamicMiddlewareRouteMap, dynamicMiddlewareRouteMap,
experimentalPPRRoutes, experimentalPPRRoutes,
hasActionOutputSupport,
}: { }: {
entryPath: string; entryPath: string;
entryDirectory: string; entryDirectory: string;
@@ -334,7 +333,6 @@ export async function getDynamicRoutes({
isServerMode?: boolean; isServerMode?: boolean;
dynamicMiddlewareRouteMap?: ReadonlyMap<string, RouteWithSrc>; dynamicMiddlewareRouteMap?: ReadonlyMap<string, RouteWithSrc>;
experimentalPPRRoutes: ReadonlySet<string>; experimentalPPRRoutes: ReadonlySet<string>;
hasActionOutputSupport: boolean;
}): Promise<RouteWithSrc[]> { }): Promise<RouteWithSrc[]> {
if (routesManifest) { if (routesManifest) {
switch (routesManifest.version) { switch (routesManifest.version) {
@@ -425,25 +423,14 @@ export async function getDynamicRoutes({
}); });
} }
if (hasActionOutputSupport) { routes.push({
routes.push({ ...route,
...route, src: route.src.replace(
src: route.src.replace( new RegExp(escapeStringRegexp('(?:/)?$')),
new RegExp(escapeStringRegexp('(?:/)?$')), '(?:\\.rsc)(?:/)?$'
'(?<nxtsuffix>(?:\\.action|\\.rsc))(?:/)?$' ),
), dest: route.dest?.replace(/($|\?)/, '.rsc$1'),
dest: route.dest?.replace(/($|\?)/, '$nxtsuffix$1'), });
});
} else {
routes.push({
...route,
src: route.src.replace(
new RegExp(escapeStringRegexp('(?:/)?$')),
'(?:\\.rsc)(?:/)?$'
),
dest: route.dest?.replace(/($|\?)/, '.rsc$1'),
});
}
routes.push(route); routes.push(route);
} }
@@ -1500,7 +1487,6 @@ export type LambdaGroup = {
isStreaming?: boolean; isStreaming?: boolean;
isPrerenders?: boolean; isPrerenders?: boolean;
isExperimentalPPR?: boolean; isExperimentalPPR?: boolean;
isActionLambda?: boolean;
isPages?: boolean; isPages?: boolean;
isApiLambda: boolean; isApiLambda: boolean;
pseudoLayer: PseudoLayer; pseudoLayer: PseudoLayer;

View File

@@ -7,4 +7,4 @@ export default function Root({ children }) {
<body>{children}</body> <body>{children}</body>
</html> </html>
); );
} }

View File

@@ -37,7 +37,6 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
).then(res => res.json()); ).then(res => res.json());
ctx.actionManifest = actionManifest; ctx.actionManifest = actionManifest;
Object.assign(ctx, info); Object.assign(ctx, info);
}); });
@@ -58,8 +57,8 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
const body = await res.text(); const body = await res.text();
expect(body).toContain('1338'); expect(body).toContain('1338');
expect(res.headers.get('x-matched-path')).toBe(path + '.action'); expect(res.headers.get('x-matched-path')).toBe(path);
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); expect(res.headers.get('x-vercel-cache')).toBe('BYPASS');
}); });
it('should bypass the static cache for a server action on a page with dynamic params', async () => { it('should bypass the static cache for a server action on a page with dynamic params', async () => {
@@ -78,8 +77,8 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
const body = await res.text(); const body = await res.text();
expect(body).toContain('1338'); expect(body).toContain('1338');
expect(res.headers.get('x-matched-path')).toBe(path + '.action'); expect(res.headers.get('x-matched-path')).toBe(path);
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); expect(res.headers.get('x-vercel-cache')).toBe('BYPASS');
}); });
it('should properly invoke the action on a dynamic page', async () => { it('should properly invoke the action on a dynamic page', async () => {
@@ -98,7 +97,7 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
const body = await res.text(); const body = await res.text();
expect(body).toContain('1338'); expect(body).toContain('1338');
expect(res.headers.get('x-matched-path')).toBe(path + '.action'); expect(res.headers.get('x-matched-path')).toBe(path);
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); expect(res.headers.get('x-vercel-cache')).toBe('MISS');
}); });
}); });
@@ -114,9 +113,9 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
); );
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(path + '.action'); expect(res.headers.get('x-matched-path')).toBe(path);
expect(res.headers.get('content-type')).toBe('text/x-component'); expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); expect(res.headers.get('x-vercel-cache')).toBe('BYPASS');
}); });
it('should bypass the static cache for a server action on a page with dynamic params', async () => { it('should bypass the static cache for a server action on a page with dynamic params', async () => {
@@ -129,9 +128,9 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
); );
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(path + '.action'); expect(res.headers.get('x-matched-path')).toBe(path);
expect(res.headers.get('content-type')).toBe('text/x-component'); expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); expect(res.headers.get('x-vercel-cache')).toBe('BYPASS');
}); });
it('should properly invoke the action on a dynamic page', async () => { it('should properly invoke the action on a dynamic page', async () => {
@@ -144,7 +143,7 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
); );
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(path + '.action'); expect(res.headers.get('x-matched-path')).toBe(path);
expect(res.headers.get('content-type')).toBe('text/x-component'); expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); expect(res.headers.get('x-vercel-cache')).toBe('MISS');
}); });
@@ -162,11 +161,9 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
); );
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe( expect(res.headers.get('x-matched-path')).toBe(path);
'/rsc/static/generate-static-params/[slug].action'
);
expect(res.headers.get('content-type')).toBe('text/x-component'); expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); expect(res.headers.get('x-vercel-cache')).toBe('BYPASS');
}); });
it('should bypass the static cache for a server action when not pre-generated', async () => { it('should bypass the static cache for a server action when not pre-generated', async () => {
@@ -179,9 +176,9 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
); );
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(page + '.action'); expect(res.headers.get('x-matched-path')).toBe(page);
expect(res.headers.get('content-type')).toBe('text/x-component'); expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); expect(res.headers.get('x-vercel-cache')).toBe('BYPASS');
}); });
}); });
}); });

View File

@@ -1 +0,0 @@
module.exports = {};

View File

@@ -428,7 +428,7 @@ it('should handle edge functions in app with basePath', async () => {
edgeFunctions.add(item); edgeFunctions.add(item);
} }
} }
expect(lambdas.size).toBe(2); expect(lambdas.size).toBe(1);
expect(edgeFunctions.size).toBe(4); expect(edgeFunctions.size).toBe(4);
}); });
@@ -452,5 +452,5 @@ it('should not generate lambdas that conflict with static index route in app wit
lambdas.add(item); lambdas.add(item);
} }
} }
expect(lambdas.size).toBe(3); expect(lambdas.size).toBe(1);
}); });