Skip to content

Commit a8bb0e3

Browse files
Skn0ttLekoArts
andauthored
fix: guard split api routes behaviour by next version (#2125)
* refactor: only evaluate flag once * fix: add activation guard for splitApiRoutes * fix: add test for behaviour * Update packages/runtime/src/helpers/flags.ts Co-authored-by: Lennart <[email protected]> --------- Co-authored-by: Lennart <[email protected]>
1 parent 5eee09f commit a8bb0e3

File tree

4 files changed

+31
-8
lines changed

4 files changed

+31
-8
lines changed

packages/runtime/src/helpers/config.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import slash from 'slash'
88

99
import { HANDLER_FUNCTION_NAME, IMAGE_FUNCTION_NAME, ODB_FUNCTION_NAME } from '../constants'
1010

11-
import { splitApiRoutes } from './flags'
1211
import type { APILambda } from './functions'
1312
import type { RoutesManifest } from './types'
1413
import { escapeStringRegexp } from './utils'
@@ -102,13 +101,13 @@ export const configureHandlerFunctions = async ({
102101
publish,
103102
ignore = [],
104103
apiLambdas,
105-
featureFlags,
104+
splitApiRoutes,
106105
}: {
107106
netlifyConfig: NetlifyConfig
108107
publish: string
109108
ignore: Array<string>
110109
apiLambdas: APILambda[]
111-
featureFlags: Record<string, unknown>
110+
splitApiRoutes: boolean
112111
}) => {
113112
const config = await getRequiredServerFiles(publish)
114113
const files = config.files || []
@@ -168,7 +167,7 @@ export const configureHandlerFunctions = async ({
168167
configureFunction(HANDLER_FUNCTION_NAME)
169168
configureFunction(ODB_FUNCTION_NAME)
170169

171-
if (splitApiRoutes(featureFlags)) {
170+
if (splitApiRoutes) {
172171
for (const apiLambda of apiLambdas) {
173172
const { functionName, includedFiles } = apiLambda
174173
netlifyConfig.functions[functionName] ||= { included_files: [] }

packages/runtime/src/helpers/flags.ts

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import destr from 'destr'
2+
import { existsSync } from 'fs-extra'
3+
import { join } from 'pathe'
24

35
/**
46
* If this flag is enabled, we generate individual Lambda functions for API Routes.
@@ -11,7 +13,19 @@ import destr from 'destr'
1113
* If disabled, we bundle all API Routes into a single function.
1214
* This is can lead to large bundle sizes.
1315
*
16+
* Relies on `next-server.js.nft.json`, which is only supported in Next.js 12+.
17+
*
1418
* Disabled by default. Can be overriden using the NEXT_SPLIT_API_ROUTES env var.
1519
*/
16-
export const splitApiRoutes = (featureFlags: Record<string, unknown>): boolean =>
17-
destr(process.env.NEXT_SPLIT_API_ROUTES) ?? featureFlags.next_split_api_routes ?? false
20+
export const splitApiRoutes = (featureFlags: Record<string, unknown>, publish: string): boolean => {
21+
const isEnabled = destr(process.env.NEXT_SPLIT_API_ROUTES) ?? featureFlags.next_split_api_routes ?? false
22+
23+
if (isEnabled && !existsSync(join(publish, 'next-server.js.nft.json'))) {
24+
console.warn(
25+
'Trace-based bundling not possible on this version of Next.js. Speed up your builds significantly by upgrading to Next.js v12 or newer.',
26+
)
27+
return false
28+
}
29+
30+
return isEnabled
31+
}

packages/runtime/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ const plugin: NetlifyPlugin = {
166166

167167
const buildId = readFileSync(join(publish, 'BUILD_ID'), 'utf8').trim()
168168

169-
const apiLambdas: APILambda[] = splitApiRoutes(featureFlags)
169+
const apiLambdas: APILambda[] = splitApiRoutes(featureFlags, publish)
170170
? await getAPILambdas(publish, appDir, pageExtensions)
171171
: await getExtendedApiRouteConfigs(publish, appDir, pageExtensions).then((extendedRoutes) =>
172172
extendedRoutes.map(packSingleFunction),
@@ -180,7 +180,7 @@ const plugin: NetlifyPlugin = {
180180
ignore,
181181
publish: relative(process.cwd(), publish),
182182
apiLambdas,
183-
featureFlags,
183+
splitApiRoutes: splitApiRoutes(featureFlags, publish),
184184
})
185185

186186
await movePublicFiles({ appDir, outdir, publish, basePath })

test/index.spec.ts

+10
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,16 @@ describe('onBuild()', () => {
727727
expect(existsSync(publicFile)).toBe(true)
728728
expect(await readJson(publicFile)).toMatchObject(expect.any(Array))
729729
})
730+
731+
it('does not split APIs when .nft.json files are unavailable', async () => {
732+
await moveNextDist()
733+
734+
await unlink(path.join(process.cwd(), '.next', 'next-server.js.nft.json'))
735+
736+
await nextRuntime.onBuild(defaultArgs)
737+
738+
expect(netlifyConfig.functions['_api_*'].node_bundler).toEqual('nft')
739+
})
730740
})
731741

732742
describe('onPostBuild', () => {

0 commit comments

Comments
 (0)