Skip to content

Commit 96edce2

Browse files
committed
conditionally use frameworski api when generating serverless and edge functions
1 parent 173cefe commit 96edce2

File tree

3 files changed

+77
-66
lines changed

3 files changed

+77
-66
lines changed

src/build/functions/edge.ts

+44-40
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import { cp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
22
import { dirname, join } from 'node:path'
33

4-
import type { IntegrationsConfig } from '@netlify/edge-functions'
4+
import type { IntegrationsConfig, Manifest, ManifestFunction } from '@netlify/edge-functions'
55
import { glob } from 'fast-glob'
66
import type { EdgeFunctionDefinition as NextDefinition } from 'next/dist/build/webpack/plugins/middleware-plugin.js'
77
import { pathToRegexp } from 'path-to-regexp'
88

99
import { EDGE_HANDLER_NAME, PluginContext } from '../plugin-context.js'
1010

11-
// const writeEdgeManifest = async (ctx: PluginContext, manifest: Manifest) => {
12-
// await mkdir(ctx.edgeFunctionsDir, { recursive: true })
13-
// await writeFile(join(ctx.edgeFunctionsDir, 'manifest.json'), JSON.stringify(manifest, null, 2))
14-
// }
11+
const writeEdgeManifest = async (ctx: PluginContext, manifest: Manifest) => {
12+
await mkdir(ctx.edgeFunctionsDir, { recursive: true })
13+
await writeFile(join(ctx.edgeFunctionsDir, 'manifest.json'), JSON.stringify(manifest, null, 2))
14+
}
1515

1616
const copyRuntime = async (ctx: PluginContext, handlerDirectory: string): Promise<void> => {
1717
const files = await glob('edge-runtime/**/*', {
@@ -84,6 +84,17 @@ const writeHandlerFile = async (ctx: PluginContext, { matchers, name, page }: Ne
8484
JSON.stringify(minimalNextConfig),
8585
)
8686

87+
const isc = ctx.useFrameworksAPI
88+
? `export const config = ${JSON.stringify({
89+
name: name.endsWith('middleware')
90+
? 'Next.js Middleware Handler'
91+
: `Next.js Edge Handler: ${page}`,
92+
pattern: augmentedMatchers.map((matcher) => matcher.regexp),
93+
cache: name.endsWith('middleware') ? undefined : 'manual',
94+
generator: `${ctx.pluginName}@${ctx.pluginVersion}`,
95+
} satisfies IntegrationsConfig)};`
96+
: ``
97+
8798
// Writing the function entry file. It wraps the middleware code with the
8899
// compatibility layer mentioned above.
89100
await writeFile(
@@ -92,16 +103,7 @@ const writeHandlerFile = async (ctx: PluginContext, { matchers, name, page }: Ne
92103
import {handleMiddleware} from './edge-runtime/middleware.ts';
93104
import handler from './server/${name}.js';
94105
export default (req, context) => handleMiddleware(req, context, handler);
95-
96-
export const config = ${JSON.stringify({
97-
name: name.endsWith('middleware')
98-
? 'Next.js Middleware Handler'
99-
: `Next.js Edge Handler: ${page}`,
100-
pattern: augmentedMatchers.map((matcher) => matcher.regexp),
101-
cache: name.endsWith('middleware') ? undefined : 'manual',
102-
generator: `${ctx.pluginName}@${ctx.pluginVersion}`,
103-
} satisfies IntegrationsConfig)};
104-
`,
106+
${isc}`,
105107
)
106108
}
107109

@@ -150,25 +152,25 @@ const createEdgeHandler = async (ctx: PluginContext, definition: NextDefinition)
150152
const getHandlerName = ({ name }: Pick<NextDefinition, 'name'>): string =>
151153
`${EDGE_HANDLER_NAME}-${name.replace(/\W/g, '-')}`
152154

153-
// const buildHandlerDefinition = (
154-
// ctx: PluginContext,
155-
// { name, matchers, page }: NextDefinition,
156-
// ): Array<ManifestFunction> => {
157-
// const fun = getHandlerName({ name })
158-
// const funName = name.endsWith('middleware')
159-
// ? 'Next.js Middleware Handler'
160-
// : `Next.js Edge Handler: ${page}`
161-
// const cache = name.endsWith('middleware') ? undefined : ('manual' as const)
162-
// const generator = `${ctx.pluginName}@${ctx.pluginVersion}`
163-
164-
// return augmentMatchers(matchers, ctx).map((matcher) => ({
165-
// function: fun,
166-
// name: funName,
167-
// pattern: matcher.regexp,
168-
// cache,
169-
// generator,
170-
// }))
171-
// }
155+
const buildHandlerDefinition = (
156+
ctx: PluginContext,
157+
{ name, matchers, page }: NextDefinition,
158+
): Array<ManifestFunction> => {
159+
const fun = getHandlerName({ name })
160+
const funName = name.endsWith('middleware')
161+
? 'Next.js Middleware Handler'
162+
: `Next.js Edge Handler: ${page}`
163+
const cache = name.endsWith('middleware') ? undefined : ('manual' as const)
164+
const generator = `${ctx.pluginName}@${ctx.pluginVersion}`
165+
166+
return augmentMatchers(matchers, ctx).map((matcher) => ({
167+
function: fun,
168+
name: funName,
169+
pattern: matcher.regexp,
170+
cache,
171+
generator,
172+
}))
173+
}
172174

173175
export const clearStaleEdgeHandlers = async (ctx: PluginContext) => {
174176
await rm(ctx.edgeFunctionsDir, { recursive: true, force: true })
@@ -182,10 +184,12 @@ export const createEdgeHandlers = async (ctx: PluginContext) => {
182184
]
183185
await Promise.all(nextDefinitions.map((def) => createEdgeHandler(ctx, def)))
184186

185-
// const netlifyDefinitions = nextDefinitions.flatMap((def) => buildHandlerDefinition(ctx, def))
186-
// const netlifyManifest: Manifest = {
187-
// version: 1,
188-
// functions: netlifyDefinitions,
189-
// }
190-
// await writeEdgeManifest(ctx, netlifyManifest)
187+
if (!ctx.useFrameworksAPI) {
188+
const netlifyDefinitions = nextDefinitions.flatMap((def) => buildHandlerDefinition(ctx, def))
189+
const netlifyManifest: Manifest = {
190+
version: 1,
191+
functions: netlifyDefinitions,
192+
}
193+
await writeEdgeManifest(ctx, netlifyManifest)
194+
}
191195
}

src/build/functions/server.ts

+20-18
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,23 @@ const copyHandlerDependencies = async (ctx: PluginContext) => {
6767
})
6868
}
6969

70-
// const writeHandlerManifest = async (ctx: PluginContext) => {
71-
// await writeFile(
72-
// join(ctx.serverHandlerRootDir, `${SERVER_HANDLER_NAME}.json`),
73-
// JSON.stringify({
74-
// config: {
75-
// name: 'Next.js Server Handler',
76-
// generator: `${ctx.pluginName}@${ctx.pluginVersion}`,
77-
// nodeBundler: 'none',
78-
// // the folders can vary in monorepos based on the folder structure of the user so we have to glob all
79-
// includedFiles: ['**'],
80-
// includedFilesBasePath: ctx.serverHandlerRootDir,
81-
// },
82-
// version: 1,
83-
// }),
84-
// 'utf-8',
85-
// )
86-
// }
70+
const writeHandlerManifest = async (ctx: PluginContext) => {
71+
await writeFile(
72+
join(ctx.serverHandlerRootDir, `${SERVER_HANDLER_NAME}.json`),
73+
JSON.stringify({
74+
config: {
75+
name: 'Next.js Server Handler',
76+
generator: `${ctx.pluginName}@${ctx.pluginVersion}`,
77+
nodeBundler: 'none',
78+
// the folders can vary in monorepos based on the folder structure of the user so we have to glob all
79+
includedFiles: ['**'],
80+
includedFilesBasePath: ctx.serverHandlerRootDir,
81+
},
82+
version: 1,
83+
}),
84+
'utf-8',
85+
)
86+
}
8787

8888
const writePackageMetadata = async (ctx: PluginContext) => {
8989
await writeFile(
@@ -143,7 +143,9 @@ export const createServerHandler = async (ctx: PluginContext) => {
143143
await copyNextServerCode(ctx)
144144
await copyNextDependencies(ctx)
145145
await copyHandlerDependencies(ctx)
146-
// await writeHandlerManifest(ctx)
146+
if (!ctx.useFrameworksAPI) {
147+
await writeHandlerManifest(ctx)
148+
}
147149
await writePackageMetadata(ctx)
148150
await writeHandlerFile(ctx)
149151

src/build/plugin-context.ts

+13-8
Original file line numberDiff line numberDiff line change
@@ -177,19 +177,16 @@ export class PluginContext {
177177
}
178178

179179
get useFrameworksAPI(): boolean {
180-
// TODO: make this conditional
181-
return true
180+
// Defining RegExp pattern in edge function inline config is only supported since 29.50.5
181+
const REQUIRED_BUILD_VERSION = '>=29.50.5'
182+
return satisfies(this.buildVersion, REQUIRED_BUILD_VERSION, { includePrerelease: true })
182183
}
183184

184185
get blobsStrategy(): 'legacy' | 'regional' | 'frameworks-api' {
185186
if (this.useFrameworksAPI) {
186187
return 'frameworks-api'
187188
}
188189

189-
if (!(this.featureFlags || {})['next-runtime-regional-blobs']) {
190-
return 'legacy'
191-
}
192-
193190
// Region-aware blobs are only available as of CLI v17.23.5 (i.e. Build v29.41.5)
194191
const REQUIRED_BUILD_VERSION = '>=29.41.5'
195192
return satisfies(this.buildVersion, REQUIRED_BUILD_VERSION, { includePrerelease: true })
@@ -202,7 +199,11 @@ export class PluginContext {
202199
* `.netlify/functions-internal`
203200
*/
204201
get serverFunctionsDir(): string {
205-
return this.resolveFromPackagePath('.netlify/v1/functions')
202+
if (this.useFrameworksAPI) {
203+
return this.resolveFromPackagePath('.netlify/v1/functions')
204+
}
205+
206+
return this.resolveFromPackagePath('.netlify/functions-internal')
206207
}
207208

208209
/** Absolute path of the server handler */
@@ -229,7 +230,11 @@ export class PluginContext {
229230
* `.netlify/edge-functions`
230231
*/
231232
get edgeFunctionsDir(): string {
232-
return this.resolveFromPackagePath('.netlify/v1/edge-functions')
233+
if (this.useFrameworksAPI) {
234+
return this.resolveFromPackagePath('.netlify/v1/edge-functions')
235+
}
236+
237+
return this.resolveFromPackagePath('.netlify/edge-functions')
233238
}
234239

235240
/** Absolute path of the edge handler */

0 commit comments

Comments
 (0)