diff --git a/packages/runtime/src/helpers/functions.ts b/packages/runtime/src/helpers/functions.ts index d397987eab..052e0b5efc 100644 --- a/packages/runtime/src/helpers/functions.ts +++ b/packages/runtime/src/helpers/functions.ts @@ -49,9 +49,13 @@ export const generateFunctions = async ( join(__dirname, '..', '..', 'lib', 'templates', 'handlerUtils.js'), join(functionsDir, functionName, 'handlerUtils.js'), ) + + const resolveSourceFile = (file: string) => join(publish, 'server', file) + const resolverSource = await getSinglePageResolver({ functionsDir, - sourceFile: join(publish, 'server', compiled), + // These extra pages are always included by Next.js + sourceFiles: [compiled, 'pages/_app.js', 'pages/_document.js', 'pages/_error.js'].map(resolveSourceFile), }) await writeFile(join(functionsDir, functionName, 'pages.js'), resolverSource) } diff --git a/packages/runtime/src/templates/getPageResolver.ts b/packages/runtime/src/templates/getPageResolver.ts index d5bc24cc43..6ca5165858 100644 --- a/packages/runtime/src/templates/getPageResolver.ts +++ b/packages/runtime/src/templates/getPageResolver.ts @@ -39,16 +39,18 @@ export const getPageResolver = async ({ publish, target }: { publish: string; ta */ export const getSinglePageResolver = async ({ functionsDir, - sourceFile, + sourceFiles, }: { functionsDir: string - sourceFile: string + sourceFiles: Array }) => { - const dependencies = await getDependenciesOfFile(sourceFile) + const dependencies = await Promise.all(sourceFiles.map((sourceFile) => getDependenciesOfFile(sourceFile))) // We don't need the actual name, just the relative path. const functionDir = resolve(functionsDir, 'functionName') - const pageFiles = [sourceFile, ...dependencies] + const deduped = [...new Set(dependencies.flat())] + + const pageFiles = [...sourceFiles, ...deduped] .map((file) => `require.resolve('${relative(functionDir, file)}')`) .sort() diff --git a/test/__snapshots__/index.js.snap b/test/__snapshots__/index.js.snap index e1a60553cd..3e0a8fc8ec 100644 --- a/test/__snapshots__/index.js.snap +++ b/test/__snapshots__/index.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`onBuild() generates a file referencing all page sources 1`] = ` +exports[`onBuild() generates a file referencing all API route sources 1`] = ` "// This file is purely to allow nft to know about these pages. It should be temporary. exports.resolvePages = () => { try { @@ -38,7 +38,7 @@ exports.resolvePages = () => { }" `; -exports[`onBuild() generates a file referencing all page sources 2`] = ` +exports[`onBuild() generates a file referencing all API route sources 2`] = ` "// This file is purely to allow nft to know about these pages. It should be temporary. exports.resolvePages = () => { try { @@ -76,6 +76,35 @@ exports.resolvePages = () => { }" `; +exports[`onBuild() generates a file referencing all page sources: for _api_hello-background-background 1`] = ` +"// This file is purely to allow nft to know about these pages. + try { + require.resolve('../../../.next/server/package.json') + require.resolve('../../../.next/server/pages/_app.js') + require.resolve('../../../.next/server/pages/_document.js') + require.resolve('../../../.next/server/pages/_error.js') + require.resolve('../../../.next/server/pages/api/hello-background.js') + require.resolve('../../../.next/server/pages/chunks/274.js') + require.resolve('../../../.next/server/pages/webpack-api-runtime.js') + require.resolve('../../../.next/server/pages/webpack-runtime.js') + } catch {}" +`; + +exports[`onBuild() generates a file referencing all page sources: for _api_hello-scheduled-handler 1`] = ` +"// This file is purely to allow nft to know about these pages. + try { + require.resolve('../../../.next/package.json') + require.resolve('../../../.next/server/package.json') + require.resolve('../../../.next/server/pages/_app.js') + require.resolve('../../../.next/server/pages/_document.js') + require.resolve('../../../.next/server/pages/_error.js') + require.resolve('../../../.next/server/pages/api/hello-scheduled.js') + require.resolve('../../../.next/server/pages/chunks/274.js') + require.resolve('../../../.next/server/pages/webpack-api-runtime.js') + require.resolve('../../../.next/server/pages/webpack-runtime.js') + } catch {}" +`; + exports[`onBuild() generates a file referencing all when publish dir is a subdirectory 1`] = ` "// This file is purely to allow nft to know about these pages. It should be temporary. exports.resolvePages = () => { diff --git a/test/index.js b/test/index.js index 26eadaad87..daa7f97581 100644 --- a/test/index.js +++ b/test/index.js @@ -533,7 +533,18 @@ describe('onBuild()', () => { expect(netlifyConfig.functions[ODB_FUNCTION_NAME].node_bundler).toEqual('nft') }) - test('generates a file referencing all page sources', async () => { + it('generates a file referencing all page sources', async () => { + await moveNextDist() + await nextRuntime.onBuild(defaultArgs) + + for (const route of ['_api_hello-background-background', '_api_hello-scheduled-handler']) { + const expected = path.resolve(constants.INTERNAL_FUNCTIONS_SRC, route, 'pages.js') + expect(existsSync(expected)).toBeTruthy() + expect(readFileSync(expected, 'utf8')).toMatchSnapshot(`for ${route}`) + } + }) + + test('generates a file referencing all API route sources', async () => { await moveNextDist() await nextRuntime.onBuild(defaultArgs) const handlerPagesFile = path.join(constants.INTERNAL_FUNCTIONS_SRC, HANDLER_FUNCTION_NAME, 'pages.js')