From 199a442f4bacffb7d315be274b8435a8997fb970 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Thu, 11 May 2023 16:16:29 +0200 Subject: [PATCH 01/20] fix: tRaCe --- packages/runtime/src/constants.ts | 6 +++--- packages/runtime/src/helpers/redirects.ts | 12 +----------- packages/runtime/src/index.ts | 11 +++++++++-- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/packages/runtime/src/constants.ts b/packages/runtime/src/constants.ts index 7bc87c82df..6fd1cc746e 100644 --- a/packages/runtime/src/constants.ts +++ b/packages/runtime/src/constants.ts @@ -8,9 +8,9 @@ export const ODB_FUNCTION_TITLE = 'Next.js ISR handler' export const IMAGE_FUNCTION_TITLE = 'next/image handler' // These are paths in .next that shouldn't be publicly accessible export const HIDDEN_PATHS = [ - '/cache/*', - '/server/*', - '/serverless/*', + '/cache', + '/server', + '/serverless', '/trace', '/traces', '/routes-manifest.json', diff --git a/packages/runtime/src/helpers/redirects.ts b/packages/runtime/src/helpers/redirects.ts index c7194a3b7b..8777951f4c 100644 --- a/packages/runtime/src/helpers/redirects.ts +++ b/packages/runtime/src/helpers/redirects.ts @@ -7,7 +7,7 @@ import type { PrerenderManifest, SsgRoute } from 'next/dist/build' import { outdent } from 'outdent' import { join } from 'pathe' -import { HANDLER_FUNCTION_PATH, HIDDEN_PATHS, ODB_FUNCTION_PATH } from '../constants' +import { HANDLER_FUNCTION_PATH, ODB_FUNCTION_PATH } from '../constants' import { isAppDirRoute, loadAppPathRoutesManifest } from './edge' import { getMiddleware } from './files' @@ -27,14 +27,6 @@ import { const matchesMiddleware = (middleware: Array, route: string): boolean => middleware.some((middlewarePath) => route.startsWith(middlewarePath)) -const generateHiddenPathRedirects = ({ basePath }: Pick): NetlifyConfig['redirects'] => - HIDDEN_PATHS.map((path) => ({ - from: `${basePath}${path}`, - to: '/404.html', - status: 404, - force: true, - })) - const generateLocaleRedirects = ({ i18n, basePath, @@ -281,8 +273,6 @@ export const generateRedirects = async ({ join(netlifyConfig.build.publish, 'routes-manifest.json'), ) - netlifyConfig.redirects.push(...generateHiddenPathRedirects({ basePath })) - if (i18n && i18n.localeDetection !== false) { netlifyConfig.redirects.push(...generateLocaleRedirects({ i18n, basePath, trailingSlash })) } diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index 07b160e24d..b75bc6e8b8 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -3,10 +3,10 @@ import { join, relative } from 'path' import type { NetlifyPlugin, NetlifyPluginOptions } from '@netlify/build' import { bold, redBright } from 'chalk' import destr from 'destr' -import { existsSync, readFileSync } from 'fs-extra' +import { existsSync, readFileSync, remove } from 'fs-extra' import { outdent } from 'outdent' -import { HANDLER_FUNCTION_NAME, ODB_FUNCTION_NAME } from './constants' +import { HANDLER_FUNCTION_NAME, ODB_FUNCTION_NAME, HIDDEN_PATHS } from './constants' import { restoreCache, saveCache } from './helpers/cache' import { getNextConfig, @@ -254,6 +254,13 @@ const plugin: NetlifyPlugin = { warnForProblematicUserRewrites({ basePath, redirects }) warnForRootRedirects({ appDir }) await warnOnApiRoutes({ FUNCTIONS_DIST }) + + for (const HIDDEN_PATH of HIDDEN_PATHS) { + const pathToDelete = join(publish, HIDDEN_PATH) + console.log({ pathToDelete }) + await remove(pathToDelete) + } + if (experimental?.appDir) { console.log( '🧪 Thank you for testing "appDir" support on Netlify. For known issues and to give feedback, visit https://ntl.fyi/next-13-feedback', From 02b19ab8814b62f9b1b29f495ba6c6064f63cd04 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 09:59:30 +0200 Subject: [PATCH 02/20] chore: add more metadata files for deletion --- packages/runtime/src/constants.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/runtime/src/constants.ts b/packages/runtime/src/constants.ts index 6fd1cc746e..160c7d5a8e 100644 --- a/packages/runtime/src/constants.ts +++ b/packages/runtime/src/constants.ts @@ -7,6 +7,7 @@ export const HANDLER_FUNCTION_TITLE = 'Next.js SSR handler' export const ODB_FUNCTION_TITLE = 'Next.js ISR handler' export const IMAGE_FUNCTION_TITLE = 'next/image handler' // These are paths in .next that shouldn't be publicly accessible + export const HIDDEN_PATHS = [ '/cache', '/server', @@ -18,6 +19,15 @@ export const HIDDEN_PATHS = [ '/prerender-manifest.json', '/react-loadable-manifest.json', '/BUILD_ID', + '/app-build-manifest.json', + '/app-path-routes-manifest.json', + '/export-marker.json', + '/images-manifest.json', + '/next-server.js.nft.json', + '/package.json', + '/prerender-manifest.js', + '/required-server-files.json', + 'static-manifest.json', ] export const ODB_FUNCTION_PATH = `/.netlify/builders/${ODB_FUNCTION_NAME}` From 7309968a159acc468a3fb907c612f764bb7268e4 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 09:59:59 +0200 Subject: [PATCH 03/20] refactor: move concrete file removal logic into it's own function --- packages/runtime/src/helpers/files.ts | 22 ++++++++++++++++++++-- packages/runtime/src/index.ts | 13 ++++--------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/packages/runtime/src/helpers/files.ts b/packages/runtime/src/helpers/files.ts index 28c6e3c84e..da3bec9318 100644 --- a/packages/runtime/src/helpers/files.ts +++ b/packages/runtime/src/helpers/files.ts @@ -2,7 +2,18 @@ import { cpus } from 'os' import type { NetlifyConfig } from '@netlify/build' import { yellowBright } from 'chalk' -import { existsSync, readJson, move, copy, writeJson, readFile, writeFile, ensureDir, readFileSync } from 'fs-extra' +import { + existsSync, + readJson, + move, + copy, + writeJson, + readFile, + writeFile, + ensureDir, + readFileSync, + remove, +} from 'fs-extra' import globby from 'globby' import { PrerenderManifest } from 'next/dist/build' import { outdent } from 'outdent' @@ -10,7 +21,7 @@ import pLimit from 'p-limit' import { join, resolve, dirname } from 'pathe' import slash from 'slash' -import { MINIMUM_REVALIDATE_SECONDS, DIVIDER } from '../constants' +import { MINIMUM_REVALIDATE_SECONDS, DIVIDER, HIDDEN_PATHS } from '../constants' import { NextConfig } from './config' import { loadPrerenderManifest } from './edge' @@ -467,3 +478,10 @@ export const movePublicFiles = async ({ await copy(publicDir, `${publish}${basePath}/`) } } + +export const removeMetadataFiles = async (publish: string) => { + for (const HIDDEN_PATH of HIDDEN_PATHS) { + const pathToDelete = join(publish, HIDDEN_PATH) + await remove(pathToDelete) + } +} diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index b75bc6e8b8..bb1379f220 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -3,10 +3,10 @@ import { join, relative } from 'path' import type { NetlifyPlugin, NetlifyPluginOptions } from '@netlify/build' import { bold, redBright } from 'chalk' import destr from 'destr' -import { existsSync, readFileSync, remove } from 'fs-extra' +import { existsSync, readFileSync } from 'fs-extra' import { outdent } from 'outdent' -import { HANDLER_FUNCTION_NAME, ODB_FUNCTION_NAME, HIDDEN_PATHS } from './constants' +import { HANDLER_FUNCTION_NAME, ODB_FUNCTION_NAME } from './constants' import { restoreCache, saveCache } from './helpers/cache' import { getNextConfig, @@ -17,7 +17,7 @@ import { } from './helpers/config' import { onPreDev } from './helpers/dev' import { writeEdgeFunctions, loadMiddlewareManifest, cleanupEdgeFunctions } from './helpers/edge' -import { moveStaticPages, movePublicFiles, patchNextFiles } from './helpers/files' +import { moveStaticPages, movePublicFiles, patchNextFiles, removeMetadataFiles } from './helpers/files' import { splitApiRoutes } from './helpers/flags' import { generateFunctions, @@ -254,12 +254,7 @@ const plugin: NetlifyPlugin = { warnForProblematicUserRewrites({ basePath, redirects }) warnForRootRedirects({ appDir }) await warnOnApiRoutes({ FUNCTIONS_DIST }) - - for (const HIDDEN_PATH of HIDDEN_PATHS) { - const pathToDelete = join(publish, HIDDEN_PATH) - console.log({ pathToDelete }) - await remove(pathToDelete) - } + await removeMetadataFiles(publish) if (experimental?.appDir) { console.log( From 271e5fe93566a429337bf1cb9d0afb8e36e7e5c6 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 10:02:03 +0200 Subject: [PATCH 04/20] chore: make hidden paths consistent --- packages/runtime/src/constants.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/runtime/src/constants.ts b/packages/runtime/src/constants.ts index 160c7d5a8e..0e8ab2ea28 100644 --- a/packages/runtime/src/constants.ts +++ b/packages/runtime/src/constants.ts @@ -7,7 +7,6 @@ export const HANDLER_FUNCTION_TITLE = 'Next.js SSR handler' export const ODB_FUNCTION_TITLE = 'Next.js ISR handler' export const IMAGE_FUNCTION_TITLE = 'next/image handler' // These are paths in .next that shouldn't be publicly accessible - export const HIDDEN_PATHS = [ '/cache', '/server', @@ -27,7 +26,7 @@ export const HIDDEN_PATHS = [ '/package.json', '/prerender-manifest.js', '/required-server-files.json', - 'static-manifest.json', + '/static-manifest.json', ] export const ODB_FUNCTION_PATH = `/.netlify/builders/${ODB_FUNCTION_NAME}` From 73a757daf955617bb21470524a088ff0a1b95bb2 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 10:16:25 +0200 Subject: [PATCH 05/20] test: update snapshot and add unit test for file removal --- test/__snapshots__/index.spec.ts.snap | 90 --------------------------- test/index.spec.ts | 17 +++++ 2 files changed, 17 insertions(+), 90 deletions(-) diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index d8ec3d361a..45ff9c95d1 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -2082,21 +2082,6 @@ Array [ "status": 200, "to": "/.netlify/functions/___netlify-handler", }, - Object { - "from": "/api/enterPreview", - "status": 200, - "to": "/.netlify/functions/api-0", - }, - Object { - "from": "/api/exitPreview", - "status": 200, - "to": "/.netlify/functions/api-0", - }, - Object { - "from": "/api/hello", - "status": 200, - "to": "/.netlify/functions/api-0", - }, Object { "from": "/api/hello-background", "status": 200, @@ -2107,21 +2092,6 @@ Array [ "status": 404, "to": "/404.html", }, - Object { - "from": "/api/revalidate", - "status": 200, - "to": "/.netlify/functions/api-0", - }, - Object { - "from": "/api/shows/:id", - "status": 200, - "to": "/.netlify/functions/api-0", - }, - Object { - "from": "/api/shows/:params/*", - "status": 200, - "to": "/.netlify/functions/api-0", - }, Object { "force": false, "from": "/app-edge", @@ -2206,24 +2176,6 @@ Array [ "status": 200, "to": "/.netlify/functions/___netlify-handler", }, - Object { - "force": true, - "from": "/BUILD_ID", - "status": 404, - "to": "/404.html", - }, - Object { - "force": true, - "from": "/build-manifest.json", - "status": 404, - "to": "/404.html", - }, - Object { - "force": true, - "from": "/cache/*", - "status": 404, - "to": "/404.html", - }, Object { "force": false, "from": "/css", @@ -2883,54 +2835,24 @@ Array [ "status": 200, "to": "/.netlify/functions/___netlify-handler", }, - Object { - "force": true, - "from": "/prerender-manifest.json", - "status": 404, - "to": "/404.html", - }, Object { "force": false, "from": "/previewTest", "status": 200, "to": "/.netlify/functions/___netlify-handler", }, - Object { - "force": true, - "from": "/react-loadable-manifest.json", - "status": 404, - "to": "/404.html", - }, Object { "force": false, "from": "/redirectme", "status": 200, "to": "/.netlify/functions/___netlify-handler", }, - Object { - "force": true, - "from": "/routes-manifest.json", - "status": 404, - "to": "/404.html", - }, Object { "force": false, "from": "/script", "status": 200, "to": "/.netlify/functions/___netlify-handler", }, - Object { - "force": true, - "from": "/server/*", - "status": 404, - "to": "/404.html", - }, - Object { - "force": true, - "from": "/serverless/*", - "status": 404, - "to": "/404.html", - }, Object { "force": false, "from": "/shows/:id", @@ -2966,17 +2888,5 @@ Array [ "status": 200, "to": "/.netlify/functions/___netlify-handler", }, - Object { - "force": true, - "from": "/trace", - "status": 404, - "to": "/404.html", - }, - Object { - "force": true, - "from": "/traces", - "status": 404, - "to": "/404.html", - }, ] `; diff --git a/test/index.spec.ts b/test/index.spec.ts index ec81feb12a..d18baa8685 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -1031,6 +1031,23 @@ describe('onPostBuild', () => { }, ]) }) + + it(`removes metadata files`, async () => { + await moveNextDist() + + // routes-manifest.json is one of metadata files that seems to be created with default demo site + // there are a lot of other files, but we will test just one + const manifestPath = path.resolve('.next/routes-manifest.json') + + expect(await pathExists(manifestPath)).toBe(true) + + await nextRuntime.onPostBuild({ + ...defaultArgs, + utils: { ...utils, cache: { save: jest.fn() }, functions: { list: jest.fn().mockResolvedValue([]) } }, + }) + + expect(await pathExists(manifestPath)).toBe(false) + }) }) describe('function helpers', () => { From f24dc38982d1040092da2490e6549c1b7c780c53 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 10:16:44 +0200 Subject: [PATCH 06/20] chore: add code comment about timing of metadata files removal --- packages/runtime/src/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index bb1379f220..e823eeebbd 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -254,6 +254,10 @@ const plugin: NetlifyPlugin = { warnForProblematicUserRewrites({ basePath, redirects }) warnForRootRedirects({ appDir }) await warnOnApiRoutes({ FUNCTIONS_DIST }) + + // we are removing metadata files from Publish directory + // we have to do this after functions were bundled as bundling still + // require those files, but we don't want to publish them await removeMetadataFiles(publish) if (experimental?.appDir) { From 3c0147fc25f0925e2ff7251ce9753417c304ebb8 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 13:23:53 +0200 Subject: [PATCH 07/20] fix: publish 404 and 500 to cdn --- packages/runtime/src/helpers/files.ts | 2 +- packages/runtime/src/helpers/utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/runtime/src/helpers/files.ts b/packages/runtime/src/helpers/files.ts index da3bec9318..9815612f1a 100644 --- a/packages/runtime/src/helpers/files.ts +++ b/packages/runtime/src/helpers/files.ts @@ -150,7 +150,7 @@ export const moveStaticPages = async ({ } } // Move all static files, except error documents and nft manifests - const pages = await globby(['{app,pages}/**/*.{html,json,rsc}', '!**/(500|404|*.js.nft).{html,json}'], { + const pages = await globby(['{app,pages}/**/*.{html,json,rsc}', '!**/*.js.nft.{html,json}'], { cwd: outputDir, dot: true, }) diff --git a/packages/runtime/src/helpers/utils.ts b/packages/runtime/src/helpers/utils.ts index 7bb84478ab..386c6f91ac 100644 --- a/packages/runtime/src/helpers/utils.ts +++ b/packages/runtime/src/helpers/utils.ts @@ -170,7 +170,7 @@ export const redirectsForNext404Route = ({ }): NetlifyConfig['redirects'] => netlifyRoutesForNextRoute({ route, buildId, i18n }).map(({ redirect, locale }) => ({ from: `${basePath}${redirect}`, - to: locale ? `${basePath}/server/pages/${locale}/404.html` : `${basePath}/server/pages/404.html`, + to: locale ? `${basePath}/${locale}/404.html` : `${basePath}/404.html`, status: 404, force, })) From 0566f2e3e621b04b083402f2d9b6cec34557890d Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 13:58:36 +0200 Subject: [PATCH 08/20] test: don't delete BUILD_ID in test env --- packages/runtime/src/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/runtime/src/constants.ts b/packages/runtime/src/constants.ts index 0e8ab2ea28..2728966d65 100644 --- a/packages/runtime/src/constants.ts +++ b/packages/runtime/src/constants.ts @@ -17,7 +17,7 @@ export const HIDDEN_PATHS = [ '/build-manifest.json', '/prerender-manifest.json', '/react-loadable-manifest.json', - '/BUILD_ID', + process.env.NODE_ENV === `test` ? false : '/BUILD_ID', '/app-build-manifest.json', '/app-path-routes-manifest.json', '/export-marker.json', @@ -27,7 +27,7 @@ export const HIDDEN_PATHS = [ '/prerender-manifest.js', '/required-server-files.json', '/static-manifest.json', -] +].filter(Boolean) export const ODB_FUNCTION_PATH = `/.netlify/builders/${ODB_FUNCTION_NAME}` export const HANDLER_FUNCTION_PATH = `/.netlify/functions/${HANDLER_FUNCTION_NAME}` From 68f699a73c94f45d431b58e1e01e507129ac6557 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 14:00:57 +0200 Subject: [PATCH 09/20] test: update snapshot --- test/__snapshots__/index.spec.ts.snap | 48 ++++++++++++++++++++------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index 45ff9c95d1..ce6b5daffc 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -1087,6 +1087,14 @@ Array [ "app/blog/sarah/second-post.rsc", "blog/sarah/second-post.rsc", ], + Array [ + "pages/en/404.html", + "en/404.html", + ], + Array [ + "pages/en/500.html", + "en/500.html", + ], Array [ "pages/en/broken-image.html", "en/broken-image.html", @@ -1207,6 +1215,14 @@ Array [ "pages/en/static.html", "en/static.html", ], + Array [ + "pages/es/404.html", + "es/404.html", + ], + Array [ + "pages/es/500.html", + "es/500.html", + ], Array [ "pages/es/broken-image.html", "es/broken-image.html", @@ -1263,6 +1279,14 @@ Array [ "pages/es/static.html", "es/static.html", ], + Array [ + "pages/fr/404.html", + "fr/404.html", + ], + Array [ + "pages/fr/500.html", + "fr/500.html", + ], Array [ "pages/fr/broken-image.html", "fr/broken-image.html", @@ -1456,7 +1480,7 @@ Array [ "force": false, "from": "/_next/data/build-id/en/getStaticProps/:id.json", "status": 404, - "to": "/server/pages/en/404.html", + "to": "/en/404.html", }, Object { "force": false, @@ -1504,7 +1528,7 @@ Array [ "force": false, "from": "/_next/data/build-id/en/getStaticProps/withRevalidate/:id.json", "status": 404, - "to": "/server/pages/en/404.html", + "to": "/en/404.html", }, Object { "force": true, @@ -1702,7 +1726,7 @@ Array [ "force": false, "from": "/_next/data/build-id/es/getStaticProps/:id.json", "status": 404, - "to": "/server/pages/es/404.html", + "to": "/es/404.html", }, Object { "force": false, @@ -1750,7 +1774,7 @@ Array [ "force": false, "from": "/_next/data/build-id/es/getStaticProps/withRevalidate/:id.json", "status": 404, - "to": "/server/pages/es/404.html", + "to": "/es/404.html", }, Object { "force": false, @@ -1912,7 +1936,7 @@ Array [ "force": false, "from": "/_next/data/build-id/fr/getStaticProps/:id.json", "status": 404, - "to": "/server/pages/fr/404.html", + "to": "/fr/404.html", }, Object { "force": false, @@ -1960,7 +1984,7 @@ Array [ "force": false, "from": "/_next/data/build-id/fr/getStaticProps/withRevalidate/:id.json", "status": 404, - "to": "/server/pages/fr/404.html", + "to": "/fr/404.html", }, Object { "force": false, @@ -2312,7 +2336,7 @@ Array [ "force": false, "from": "/es/getStaticProps/:id", "status": 404, - "to": "/server/pages/es/404.html", + "to": "/es/404.html", }, Object { "force": false, @@ -2360,7 +2384,7 @@ Array [ "force": false, "from": "/es/getStaticProps/withRevalidate/:id", "status": 404, - "to": "/server/pages/es/404.html", + "to": "/es/404.html", }, Object { "force": false, @@ -2552,7 +2576,7 @@ Array [ "force": false, "from": "/fr/getStaticProps/:id", "status": 404, - "to": "/server/pages/fr/404.html", + "to": "/fr/404.html", }, Object { "force": false, @@ -2600,7 +2624,7 @@ Array [ "force": false, "from": "/fr/getStaticProps/withRevalidate/:id", "status": 404, - "to": "/server/pages/fr/404.html", + "to": "/fr/404.html", }, Object { "force": false, @@ -2708,7 +2732,7 @@ Array [ "force": false, "from": "/getStaticProps/:id", "status": 404, - "to": "/server/pages/en/404.html", + "to": "/en/404.html", }, Object { "force": false, @@ -2756,7 +2780,7 @@ Array [ "force": false, "from": "/getStaticProps/withRevalidate/:id", "status": 404, - "to": "/server/pages/en/404.html", + "to": "/en/404.html", }, Object { "force": true, From bee62a1889dc3674abc7c00a71c83aaf2cddcaa7 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 14:04:36 +0200 Subject: [PATCH 10/20] fix: typescript gods --- packages/runtime/src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime/src/constants.ts b/packages/runtime/src/constants.ts index 2728966d65..3c8e8c7855 100644 --- a/packages/runtime/src/constants.ts +++ b/packages/runtime/src/constants.ts @@ -17,7 +17,7 @@ export const HIDDEN_PATHS = [ '/build-manifest.json', '/prerender-manifest.json', '/react-loadable-manifest.json', - process.env.NODE_ENV === `test` ? false : '/BUILD_ID', + process.env.NODE_ENV === `test` ? `` : '/BUILD_ID', '/app-build-manifest.json', '/app-path-routes-manifest.json', '/export-marker.json', From c94a81c809706db507b1db9121966eb9810aa810 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 15:19:36 +0200 Subject: [PATCH 11/20] chore: dummy commit From 8f28acde549ea3eab3232b13acfe1a7ebfee08cd Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 15:43:55 +0200 Subject: [PATCH 12/20] chore: dummy commit2 From c303d75c5e997dfeea75251b6e32014160be349b Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 15:54:56 +0200 Subject: [PATCH 13/20] chore: dummy commit3 --- packages/runtime/src/constants.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/runtime/src/constants.ts b/packages/runtime/src/constants.ts index 3c8e8c7855..a3342df937 100644 --- a/packages/runtime/src/constants.ts +++ b/packages/runtime/src/constants.ts @@ -6,6 +6,7 @@ export const NEXT_PLUGIN = '@netlify/plugin-nextjs' export const HANDLER_FUNCTION_TITLE = 'Next.js SSR handler' export const ODB_FUNCTION_TITLE = 'Next.js ISR handler' export const IMAGE_FUNCTION_TITLE = 'next/image handler' + // These are paths in .next that shouldn't be publicly accessible export const HIDDEN_PATHS = [ '/cache', From d228aed0097148cbc24752fd79f0209c87d1c07b Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 16:19:23 +0200 Subject: [PATCH 14/20] test: update snapshot --- test/__snapshots__/index.spec.ts.snap | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index ce6b5daffc..a322148a33 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -2106,6 +2106,21 @@ Array [ "status": 200, "to": "/.netlify/functions/___netlify-handler", }, + Object { + "from": "/api/enterPreview", + "status": 200, + "to": "/.netlify/functions/api-0", + }, + Object { + "from": "/api/exitPreview", + "status": 200, + "to": "/.netlify/functions/api-0", + }, + Object { + "from": "/api/hello", + "status": 200, + "to": "/.netlify/functions/api-0", + }, Object { "from": "/api/hello-background", "status": 200, @@ -2116,6 +2131,21 @@ Array [ "status": 404, "to": "/404.html", }, + Object { + "from": "/api/revalidate", + "status": 200, + "to": "/.netlify/functions/api-0", + }, + Object { + "from": "/api/shows/:id", + "status": 200, + "to": "/.netlify/functions/api-0", + }, + Object { + "from": "/api/shows/:params/*", + "status": 200, + "to": "/.netlify/functions/api-0", + }, Object { "force": false, "from": "/app-edge", From 3e9080d5d55b0fe1b0f34c536086708ad9b80eee Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 16:28:06 +0200 Subject: [PATCH 15/20] test: use different dedicated env var to skip deleting BUILD_ID --- packages/runtime/src/constants.ts | 5 +++-- test/e2e/next-test-lib/next-modes/next-deploy.ts | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/runtime/src/constants.ts b/packages/runtime/src/constants.ts index a3342df937..842bac29d9 100644 --- a/packages/runtime/src/constants.ts +++ b/packages/runtime/src/constants.ts @@ -1,3 +1,5 @@ +import destr from 'destr' + export const HANDLER_FUNCTION_NAME = '___netlify-handler' export const ODB_FUNCTION_NAME = '___netlify-odb-handler' export const IMAGE_FUNCTION_NAME = '_ipx' @@ -6,7 +8,6 @@ export const NEXT_PLUGIN = '@netlify/plugin-nextjs' export const HANDLER_FUNCTION_TITLE = 'Next.js SSR handler' export const ODB_FUNCTION_TITLE = 'Next.js ISR handler' export const IMAGE_FUNCTION_TITLE = 'next/image handler' - // These are paths in .next that shouldn't be publicly accessible export const HIDDEN_PATHS = [ '/cache', @@ -18,7 +19,7 @@ export const HIDDEN_PATHS = [ '/build-manifest.json', '/prerender-manifest.json', '/react-loadable-manifest.json', - process.env.NODE_ENV === `test` ? `` : '/BUILD_ID', + destr(process.env.NEXT_KEEP_BUILD_ID) ? `` : '/BUILD_ID', '/app-build-manifest.json', '/app-path-routes-manifest.json', '/export-marker.json', diff --git a/test/e2e/next-test-lib/next-modes/next-deploy.ts b/test/e2e/next-test-lib/next-modes/next-deploy.ts index 793f41ea18..f55fb2940e 100644 --- a/test/e2e/next-test-lib/next-modes/next-deploy.ts +++ b/test/e2e/next-test-lib/next-modes/next-deploy.ts @@ -74,6 +74,7 @@ export class NextDeployInstance extends NextInstance { NETLIFY_SITE_ID: this._netlifySiteId, NODE_ENV: 'production', DISABLE_IPX: platform() === 'linux' ? undefined : '1', + NEXT_KEEP_BUILD_ID: 'true', }, }) From 0fad9fc4e9f78a98943258e836e7ba77c69a376b Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 16:30:39 +0200 Subject: [PATCH 16/20] test: update utils.spec.ts assertions --- test/helpers/utils.spec.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/helpers/utils.spec.ts b/test/helpers/utils.spec.ts index 19d70fcae2..a6c5c9398c 100644 --- a/test/helpers/utils.spec.ts +++ b/test/helpers/utils.spec.ts @@ -149,8 +149,8 @@ describe('redirectsForNext404Route', () => { } expect(redirectsForNext404Route(mockRoute)).toStrictEqual([ - { force: false, from: '/_next/data/test/test.json', status: 404, to: '/server/pages/404.html' }, - { force: false, from: '/test', status: 404, to: '/server/pages/404.html' }, + { force: false, from: '/_next/data/test/test.json', status: 404, to: '/404.html' }, + { force: false, from: '/test', status: 404, to: '/404.html' }, ]) }) @@ -166,12 +166,12 @@ describe('redirectsForNext404Route', () => { } expect(redirectsForNext404Route(mockRoute)).toStrictEqual([ - { force: false, from: '/_next/data/test/en/test.json', status: 404, to: '/server/pages/en/404.html' }, - { force: false, from: '/test', status: 404, to: '/server/pages/en/404.html' }, - { force: false, from: '/_next/data/test/es/test.json', status: 404, to: '/server/pages/es/404.html' }, - { force: false, from: '/es/test', status: 404, to: '/server/pages/es/404.html' }, - { force: false, from: '/_next/data/test/fr/test.json', status: 404, to: '/server/pages/fr/404.html' }, - { force: false, from: '/fr/test', status: 404, to: '/server/pages/fr/404.html' }, + { force: false, from: '/_next/data/test/en/test.json', status: 404, to: '/en/404.html' }, + { force: false, from: '/test', status: 404, to: '/en/404.html' }, + { force: false, from: '/_next/data/test/es/test.json', status: 404, to: '/es/404.html' }, + { force: false, from: '/es/test', status: 404, to: '/es/404.html' }, + { force: false, from: '/_next/data/test/fr/test.json', status: 404, to: '/fr/404.html' }, + { force: false, from: '/fr/test', status: 404, to: '/fr/404.html' }, ]) }) @@ -182,13 +182,13 @@ describe('redirectsForNext404Route', () => { force: false, from: '/_next/data/test/getStaticProps/:id.json', status: 404, - to: '/server/pages/404.html', + to: '/404.html', }, { force: false, from: '/getStaticProps/:id', status: 404, - to: '/server/pages/404.html', + to: '/404.html', }, ], dynamicRoutesThatMatchMiddleware: [], From 1bef70c8c5e86494385235ca560ab7e1c4c23610 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 16:53:52 +0200 Subject: [PATCH 17/20] test: keep all the metadata for e2e tests --- packages/runtime/src/constants.ts | 44 ++++++++++--------- .../next-test-lib/next-modes/next-deploy.ts | 2 +- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/packages/runtime/src/constants.ts b/packages/runtime/src/constants.ts index 842bac29d9..998f25ea34 100644 --- a/packages/runtime/src/constants.ts +++ b/packages/runtime/src/constants.ts @@ -9,27 +9,29 @@ export const HANDLER_FUNCTION_TITLE = 'Next.js SSR handler' export const ODB_FUNCTION_TITLE = 'Next.js ISR handler' export const IMAGE_FUNCTION_TITLE = 'next/image handler' // These are paths in .next that shouldn't be publicly accessible -export const HIDDEN_PATHS = [ - '/cache', - '/server', - '/serverless', - '/trace', - '/traces', - '/routes-manifest.json', - '/build-manifest.json', - '/prerender-manifest.json', - '/react-loadable-manifest.json', - destr(process.env.NEXT_KEEP_BUILD_ID) ? `` : '/BUILD_ID', - '/app-build-manifest.json', - '/app-path-routes-manifest.json', - '/export-marker.json', - '/images-manifest.json', - '/next-server.js.nft.json', - '/package.json', - '/prerender-manifest.js', - '/required-server-files.json', - '/static-manifest.json', -].filter(Boolean) +export const HIDDEN_PATHS = destr(process.env.NEXT_KEEP_METADATA_FILES) + ? [] + : [ + '/cache', + '/server', + '/serverless', + '/trace', + '/traces', + '/routes-manifest.json', + '/build-manifest.json', + '/prerender-manifest.json', + '/react-loadable-manifest.json', + '/BUILD_ID', + '/app-build-manifest.json', + '/app-path-routes-manifest.json', + '/export-marker.json', + '/images-manifest.json', + '/next-server.js.nft.json', + '/package.json', + '/prerender-manifest.js', + '/required-server-files.json', + '/static-manifest.json', + ] export const ODB_FUNCTION_PATH = `/.netlify/builders/${ODB_FUNCTION_NAME}` export const HANDLER_FUNCTION_PATH = `/.netlify/functions/${HANDLER_FUNCTION_NAME}` diff --git a/test/e2e/next-test-lib/next-modes/next-deploy.ts b/test/e2e/next-test-lib/next-modes/next-deploy.ts index f55fb2940e..1463cbc1af 100644 --- a/test/e2e/next-test-lib/next-modes/next-deploy.ts +++ b/test/e2e/next-test-lib/next-modes/next-deploy.ts @@ -74,7 +74,7 @@ export class NextDeployInstance extends NextInstance { NETLIFY_SITE_ID: this._netlifySiteId, NODE_ENV: 'production', DISABLE_IPX: platform() === 'linux' ? undefined : '1', - NEXT_KEEP_BUILD_ID: 'true', + NEXT_KEEP_METADATA_FILES: 'true', }, }) From 465bcdabeff6e643741a68fb756128d83aa91498 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 17 May 2023 17:12:11 +0200 Subject: [PATCH 18/20] chore: update comment --- packages/runtime/src/helpers/files.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime/src/helpers/files.ts b/packages/runtime/src/helpers/files.ts index 9815612f1a..d565be269e 100644 --- a/packages/runtime/src/helpers/files.ts +++ b/packages/runtime/src/helpers/files.ts @@ -149,7 +149,7 @@ export const moveStaticPages = async ({ console.warn('Error moving file', source, error) } } - // Move all static files, except error documents and nft manifests + // Move all static files, except nft manifests const pages = await globby(['{app,pages}/**/*.{html,json,rsc}', '!**/*.js.nft.{html,json}'], { cwd: outputDir, dot: true, From d709eb1dde0e2fccd2304b65de19eb1428ef17db Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Thu, 18 May 2023 17:25:27 +0200 Subject: [PATCH 19/20] perf: delete files concurrently instead of 1 by 1 --- packages/runtime/src/helpers/files.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/runtime/src/helpers/files.ts b/packages/runtime/src/helpers/files.ts index d565be269e..f89dabc038 100644 --- a/packages/runtime/src/helpers/files.ts +++ b/packages/runtime/src/helpers/files.ts @@ -480,8 +480,13 @@ export const movePublicFiles = async ({ } export const removeMetadataFiles = async (publish: string) => { - for (const HIDDEN_PATH of HIDDEN_PATHS) { + // Limit concurrent file moves to number of cpus or 2 if there is only 1 + const limit = pLimit(Math.max(2, cpus().length)) + + const removePromises = HIDDEN_PATHS.map((HIDDEN_PATH) => { const pathToDelete = join(publish, HIDDEN_PATH) - await remove(pathToDelete) - } + return limit(() => remove(pathToDelete)) + }) + + await Promise.all(removePromises) } From 33994554779e2e7755c55e4342b039f8c9e8fcc6 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Thu, 18 May 2023 17:27:12 +0200 Subject: [PATCH 20/20] chore: update comment --- packages/runtime/src/helpers/files.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime/src/helpers/files.ts b/packages/runtime/src/helpers/files.ts index f89dabc038..93bf733ade 100644 --- a/packages/runtime/src/helpers/files.ts +++ b/packages/runtime/src/helpers/files.ts @@ -480,7 +480,7 @@ export const movePublicFiles = async ({ } export const removeMetadataFiles = async (publish: string) => { - // Limit concurrent file moves to number of cpus or 2 if there is only 1 + // Limit concurrent deletions to number of cpus or 2 if there is only 1 const limit = pLimit(Math.max(2, cpus().length)) const removePromises = HIDDEN_PATHS.map((HIDDEN_PATH) => {