From b595f1bd3eaef7c051ab70bfe0d1d1e5e413dcc4 Mon Sep 17 00:00:00 2001 From: Nick Babcock Date: Tue, 27 Aug 2024 06:35:44 -0500 Subject: [PATCH 1/3] Add CLI option to ignore invalid functions The presence of invalid functions shouldn't force a build failure as a deployment can still be valid (and even correct as outlined in #845) with invalid functions. This commit adds a `--force` cli option (bike-shedding welcomed) that allows users to opt to ignore invalid functions (and skip more checks in the future?). Closes #845 --- .../src/buildApplication/buildApplication.ts | 10 +++- .../processVercelFunctions/index.ts | 1 + .../invalidFunctions.ts | 7 ++- packages/next-on-pages/src/cli.ts | 2 + .../invalidFunctions.test.ts | 50 +++++++++++++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/packages/next-on-pages/src/buildApplication/buildApplication.ts b/packages/next-on-pages/src/buildApplication/buildApplication.ts index 92741382b..ed55a55ea 100644 --- a/packages/next-on-pages/src/buildApplication/buildApplication.ts +++ b/packages/next-on-pages/src/buildApplication/buildApplication.ts @@ -30,6 +30,7 @@ export async function buildApplication({ watch, outdir: outputDir, customEntrypoint, + force, }: Pick< CliOptions, | 'skipBuild' @@ -38,6 +39,7 @@ export async function buildApplication({ | 'watch' | 'outdir' | 'customEntrypoint' + | 'force' >) { const pm = await getPackageManager(); @@ -87,6 +89,7 @@ export async function buildApplication({ disableChunksDedup, disableWorkerMinification, customEntrypoint, + force, }); const totalBuildTime = ((Date.now() - buildStartTime) / 1000).toFixed(2); @@ -99,9 +102,13 @@ async function prepareAndBuildWorker( disableChunksDedup, disableWorkerMinification, customEntrypoint, + force, }: Pick< CliOptions, - 'disableChunksDedup' | 'disableWorkerMinification' | 'customEntrypoint' + | 'disableChunksDedup' + | 'disableWorkerMinification' + | 'customEntrypoint' + | 'force' >, ): Promise { let vercelConfig: VercelConfig; @@ -137,6 +144,7 @@ async function prepareAndBuildWorker( nopDistDir, disableChunksDedup, vercelConfig, + ignoreInvalidFunctions: force, }); } diff --git a/packages/next-on-pages/src/buildApplication/processVercelFunctions/index.ts b/packages/next-on-pages/src/buildApplication/processVercelFunctions/index.ts index d980a75e2..55507821b 100644 --- a/packages/next-on-pages/src/buildApplication/processVercelFunctions/index.ts +++ b/packages/next-on-pages/src/buildApplication/processVercelFunctions/index.ts @@ -37,6 +37,7 @@ export type ProcessVercelFunctionsOpts = { nopDistDir: string; disableChunksDedup?: boolean; vercelConfig: VercelConfig; + ignoreInvalidFunctions: boolean; }; export type ProcessedVercelFunctions = { diff --git a/packages/next-on-pages/src/buildApplication/processVercelFunctions/invalidFunctions.ts b/packages/next-on-pages/src/buildApplication/processVercelFunctions/invalidFunctions.ts index d6d92d729..f84fb2430 100644 --- a/packages/next-on-pages/src/buildApplication/processVercelFunctions/invalidFunctions.ts +++ b/packages/next-on-pages/src/buildApplication/processVercelFunctions/invalidFunctions.ts @@ -14,7 +14,7 @@ import { isUsingAppRouter, isUsingPagesRouter } from '../getVercelConfig'; type InvalidFunctionsOpts = Pick< ProcessVercelFunctionsOpts, 'functionsDir' | 'vercelConfig' ->; +> & { ignoreInvalidFunctions?: boolean }; /** * Checks if there are any invalid functions from the Vercel build output. @@ -46,7 +46,10 @@ export async function checkInvalidFunctions( await tryToFixInvalidFuncsWithValidIndexAlternative(collectedFunctions); await tryToFixInvalidDynamicISRFuncs(collectedFunctions); - if (collectedFunctions.invalidFunctions.size > 0) { + if ( + collectedFunctions.invalidFunctions.size > 0 && + !opts.ignoreInvalidFunctions + ) { await printInvalidFunctionsErrorMessage( collectedFunctions.invalidFunctions, ); diff --git a/packages/next-on-pages/src/cli.ts b/packages/next-on-pages/src/cli.ts index 277d2ce94..efadd480a 100644 --- a/packages/next-on-pages/src/cli.ts +++ b/packages/next-on-pages/src/cli.ts @@ -62,6 +62,7 @@ program '--custom-entrypoint ', 'Wrap the generated worker for your application in a custom worker entrypoint', ) + .option('-f, --force', 'Ignore checks for edge runtime compatibility', false) .enablePositionalOptions(false) .version( nextOnPagesVersion, @@ -79,6 +80,7 @@ export type CliOptions = { info?: boolean; outdir: string; customEntrypoint?: string; + force: boolean; }; export function parseCliArgs(): CliOptions { diff --git a/packages/next-on-pages/tests/src/buildApplication/processVercelFunctions/invalidFunctions.test.ts b/packages/next-on-pages/tests/src/buildApplication/processVercelFunctions/invalidFunctions.test.ts index 8cb1bb226..013202d2c 100644 --- a/packages/next-on-pages/tests/src/buildApplication/processVercelFunctions/invalidFunctions.test.ts +++ b/packages/next-on-pages/tests/src/buildApplication/processVercelFunctions/invalidFunctions.test.ts @@ -341,4 +341,54 @@ describe('checkInvalidFunctions', () => { mockedConsoleError.restore(); mockedConsoleWarn.restore(); }); + + test('should ignore invalid functions when opted in', async () => { + const processExitMock = vi + .spyOn(process, 'exit') + .mockImplementation(async () => undefined as never); + + const { collectedFunctions, restoreFsMock } = await collectFunctionsFrom({ + functions: { + '[dynamic-1].func': prerenderFuncDir, + 'edge-route.func': edgeFuncDir, + }, + }); + + const opts = { + functionsDir, + outputDir: resolve('.vercel/output/static'), + vercelConfig: { version: 3 as const }, + ignoreInvalidFunctions: true, + }; + + await processEdgeFunctions(collectedFunctions); + await processPrerenderFunctions(collectedFunctions, opts); + await checkInvalidFunctions(collectedFunctions, opts); + restoreFsMock(); + + const { + edgeFunctions, + prerenderedFunctions, + invalidFunctions, + ignoredFunctions, + } = collectedFunctions; + + expect(edgeFunctions.size).toEqual(1); + expect(prerenderedFunctions.size).toEqual(0); + expect(invalidFunctions.size).toEqual(1); + expect(ignoredFunctions.size).toEqual(0); + + expect(getRouteInfo(edgeFunctions, 'edge-route.func')).toEqual({ + path: '/edge-route', + overrides: [], + }); + + expect([...invalidFunctions.keys()]).toEqual([ + resolve(functionsDir, '[dynamic-1].func'), + ]); + + expect(processExitMock).not.toBeCalled(); + + processExitMock.mockRestore(); + }); }); From b10ba5ba0fd73e019eac984fd0505669511f51aa Mon Sep 17 00:00:00 2001 From: Nick Babcock Date: Tue, 27 Aug 2024 06:44:08 -0500 Subject: [PATCH 2/3] Add changeset --- .changeset/hot-forks-try.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/hot-forks-try.md diff --git a/.changeset/hot-forks-try.md b/.changeset/hot-forks-try.md new file mode 100644 index 000000000..9d6a44364 --- /dev/null +++ b/.changeset/hot-forks-try.md @@ -0,0 +1,5 @@ +--- +'@cloudflare/next-on-pages': minor +--- + +Add `force` CLI option to ignore invalid functions From 9f9e501210c06795ed1eeba7b8038acbef041fbd Mon Sep 17 00:00:00 2001 From: Nick Babcock Date: Tue, 27 Aug 2024 08:10:27 -0500 Subject: [PATCH 3/3] Fix type checks --- packages/next-on-pages/tests/_helpers/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/next-on-pages/tests/_helpers/index.ts b/packages/next-on-pages/tests/_helpers/index.ts index ed9b99cf2..14db914af 100644 --- a/packages/next-on-pages/tests/_helpers/index.ts +++ b/packages/next-on-pages/tests/_helpers/index.ts @@ -223,6 +223,7 @@ export async function createRouterTestData( nopDistDir: join(workerJsDir, '__next-on-pages-dist__'), disableChunksDedup: true, vercelConfig: { version: 3 }, + ignoreInvalidFunctions: false, }); const staticAssets = await getVercelStaticAssets();