Skip to content

Commit 9a087b1

Browse files
authoredJun 24, 2024··
fix: combine functions from Frameworks API and internal directories (#5734)
* fix: combine functions from Frameworks API and internal directories * chore: fix test
1 parent 77980fa commit 9a087b1

File tree

15 files changed

+125
-15
lines changed

15 files changed

+125
-15
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ packages/*/lib/
3030
!**/fixtures/**/functions_*/.netlify/edge-functions/manifest.json
3131
!**/fixtures/**/monorepo/**/.netlify
3232
!**/tests/deploy_config/fixtures/**/.netlify
33+
**/plugins/deno-cli
3334

3435
lib

‎packages/build/src/plugins_core/edge_functions/index.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,11 @@ const coreStep = async function ({
5353
const distImportMapPath = join(dirname(internalSrcPath), IMPORT_MAP_FILENAME)
5454
const srcPath = srcDirectory ? resolve(buildDir, srcDirectory) : undefined
5555
const frameworksAPISrcPath = resolve(buildDir, packagePath || '', FRAMEWORKS_API_EDGE_FUNCTIONS_ENDPOINT)
56-
57-
let generatedFunctionsPath = internalSrcPath
56+
const generatedFunctionPaths = [internalSrcPath]
5857

5958
if (featureFlags.netlify_build_frameworks_api) {
6059
if (await pathExists(frameworksAPISrcPath)) {
61-
generatedFunctionsPath = frameworksAPISrcPath
60+
generatedFunctionPaths.unshift(frameworksAPISrcPath)
6261
}
6362

6463
const frameworkImportMap = resolve(
@@ -73,7 +72,7 @@ const coreStep = async function ({
7372
}
7473
}
7574

76-
const sourcePaths = [generatedFunctionsPath, srcPath].filter(Boolean) as string[]
75+
const sourcePaths = [...generatedFunctionPaths, srcPath].filter(Boolean) as string[]
7776

7877
logFunctions({ frameworksAPISrcPath, internalSrcDirectory, internalSrcPath, logs, srcDirectory, srcPath })
7978

@@ -89,7 +88,7 @@ const coreStep = async function ({
8988
// no-op
9089
}
9190

92-
let vendorDirectory
91+
let vendorDirectory: string | undefined
9392

9493
// If we're building locally, set a vendor directory in `internalSrcPath`.
9594
// This makes Edge Bundler keep the vendor files around after the build,
@@ -115,7 +114,7 @@ const coreStep = async function ({
115114
importMapPaths,
116115
userLogger: (...args) => log(logs, reduceLogLines(args)),
117116
systemLogger: systemLog,
118-
internalSrcFolder: generatedFunctionsPath,
117+
internalSrcFolder: generatedFunctionPaths,
119118
bootstrapURL: edgeFunctionsBootstrapURL,
120119
vendorDirectory,
121120
})

‎packages/build/src/plugins_core/functions/index.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,12 @@ const coreStep = async function ({
151151
}
152152
}
153153

154-
const hasFrameworkFunctions = frameworkFunctions.length !== 0
155-
156154
logFunctionsToBundle({
157155
logs,
158156
userFunctions,
159157
userFunctionsSrc: relativeFunctionsSrc,
160158
userFunctionsSrcExists: functionsSrcExists,
161-
internalFunctions: hasFrameworkFunctions ? [] : internalFunctions,
159+
internalFunctions,
162160
internalFunctionsSrc: relativeInternalFunctionsSrc,
163161
frameworkFunctions,
164162
})
@@ -175,7 +173,7 @@ const coreStep = async function ({
175173
functionsDist,
176174
functionsSrc,
177175
frameworkFunctionsSrc,
178-
internalFunctionsSrc: hasFrameworkFunctions ? undefined : internalFunctionsSrc,
176+
internalFunctionsSrc,
179177
isRunningLocally,
180178
logs,
181179
repositoryRoot,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default async () => new Response("Hello")
2+
3+
export const config = {
4+
excludedPath: "/internal/skip_*",
5+
generator: "Hello",
6+
path: "/internal/*"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { greeting } from "greeting"
2+
3+
export default async () => new Response(greeting)
4+
5+
export const config = {
6+
excludedPath: "/framework/skip_*",
7+
generator: "Hello",
8+
path: "/framework/*"
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"imports": {
3+
"greeting": "./util/greeting.ts"
4+
}
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const greeting = "Hello world"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default async () => new Response('Hello world')
2+
3+
export const config = {
4+
path: "/user"
5+
}

‎packages/build/tests/edge_functions/snapshots/tests.js.md

+42
Original file line numberDiff line numberDiff line change
@@ -787,3 +787,45 @@ Generated by [AVA](https://avajs.dev).
787787
────────────────────────────────────────────────────────────────␊
788788
789789
(Netlify Build completed in 1ms)`
790+
791+
## builds both edge functions generated with the Frameworks API and the ones in the internal directory
792+
793+
> Snapshot 1
794+
795+
`␊
796+
Netlify Build ␊
797+
────────────────────────────────────────────────────────────────␊
798+
799+
> Version␊
800+
@netlify/build 1.0.0␊
801+
802+
> Flags␊
803+
debug: false␊
804+
805+
> Current directory␊
806+
packages/build/tests/edge_functions/fixtures/functions_user_internal_framework␊
807+
808+
> Config file␊
809+
No config file was defined: using default values.␊
810+
811+
> Context␊
812+
production␊
813+
814+
Edge Functions bundling ␊
815+
────────────────────────────────────────────────────────────────␊
816+
817+
Packaging Edge Functions from .netlify/edge-functions directory:␊
818+
- function-3␊
819+
820+
Packaging Edge Functions generated by your framework:␊
821+
- function-2␊
822+
823+
Packaging Edge Functions from netlify/edge-functions directory:␊
824+
- function-1␊
825+
826+
(Edge Functions bundling completed in 1ms)␊
827+
828+
Netlify Build Complete ␊
829+
────────────────────────────────────────────────────────────────␊
830+
831+
(Netlify Build completed in 1ms)`
Binary file not shown.

‎packages/build/tests/edge_functions/tests.js

+37
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,40 @@ test.serial('builds edge functions generated with the Frameworks API', async (t)
235235
path: '/framework/*',
236236
})
237237
})
238+
239+
test.serial(
240+
'builds both edge functions generated with the Frameworks API and the ones in the internal directory',
241+
async (t) => {
242+
const output = await new Fixture('./fixtures/functions_user_internal_framework')
243+
.withFlags({
244+
debug: false,
245+
featureFlags: { netlify_build_frameworks_api: true },
246+
mode: 'buildbot',
247+
})
248+
.runWithBuild()
249+
250+
t.snapshot(normalizeOutput(output))
251+
252+
const { routes } = await assertManifest(t, 'functions_user_internal_framework')
253+
254+
t.is(routes.length, 3)
255+
t.deepEqual(routes[0], {
256+
function: 'function-2',
257+
pattern: '^/framework(?:/(.*))/?$',
258+
excluded_patterns: ['^/framework/skip_(.*)/?$'],
259+
path: '/framework/*',
260+
})
261+
t.deepEqual(routes[1], {
262+
function: 'function-3',
263+
pattern: '^/internal(?:/(.*))/?$',
264+
excluded_patterns: ['^/internal/skip_(.*)/?$'],
265+
path: '/internal/*',
266+
})
267+
t.deepEqual(routes[2], {
268+
function: 'function-1',
269+
pattern: '^/user/?$',
270+
excluded_patterns: [],
271+
path: '/user',
272+
})
273+
},
274+
)

‎packages/build/tests/functions/snapshots/tests.js.md

+3
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,9 @@ Generated by [AVA](https://avajs.dev).
408408
Functions bundling ␊
409409
────────────────────────────────────────────────────────────────␊
410410
411+
Packaging Functions from .netlify/functions-internal directory:␊
412+
- server-internal.mjs␊
413+
411414
Packaging Functions generated by your framework:␊
412415
- server.mjs␊
413416
Binary file not shown.

‎packages/build/tests/functions/tests.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ test('Functions: legacy `.netlify/functions-internal` directory is ignored if th
147147
t.true(functionsDist.includes('manifest.json'))
148148
t.true(functionsDist.includes('server.zip'))
149149
t.true(functionsDist.includes('user.zip'))
150-
t.false(functionsDist.includes('server-internal.zip'))
150+
t.true(functionsDist.includes('server-internal.zip'))
151151

152152
t.snapshot(normalizeOutput(output))
153153
})

‎packages/edge-bundler/node/bundler.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { getLogger, LogFunction, Logger } from './logger.js'
2020
import { writeManifest } from './manifest.js'
2121
import { vendorNPMSpecifiers } from './npm_dependencies.js'
2222
import { ensureLatestTypes } from './types.js'
23+
import { nonNullable } from './utils/non_nullable.js'
2324

2425
export interface BundleOptions {
2526
basePath?: string
@@ -30,7 +31,7 @@ export interface BundleOptions {
3031
distImportMapPath?: string
3132
featureFlags?: FeatureFlags
3233
importMapPaths?: (string | undefined)[]
33-
internalSrcFolder?: string
34+
internalSrcFolder?: string | string[]
3435
onAfterDownload?: OnAfterDownloadHook
3536
onBeforeDownload?: OnBeforeDownloadHook
3637
rootPath?: string
@@ -92,14 +93,16 @@ export const bundle = async (
9293
// not actually included in the bundle.
9394
const externals = deployConfig.layers.map((layer) => layer.name)
9495

95-
const userSourceDirectories = sourceDirectories.filter((dir) => dir !== internalSrcFolder)
96+
const internalSrcFolders = (Array.isArray(internalSrcFolder) ? internalSrcFolder : [internalSrcFolder]).filter(
97+
nonNullable,
98+
)
99+
const userSourceDirectories = sourceDirectories.filter((dir) => !internalSrcFolders.includes(dir))
96100

97101
const importMap = new ImportMap()
98-
99102
await importMap.addFiles([deployConfig?.importMap, ...importMapPaths], logger)
100103

101104
const userFunctions = userSourceDirectories.length === 0 ? [] : await findFunctions(userSourceDirectories)
102-
const internalFunctions = internalSrcFolder ? await findFunctions([internalSrcFolder]) : []
105+
const internalFunctions = internalSrcFolder ? await findFunctions(internalSrcFolders) : []
103106
const functions = [...internalFunctions, ...userFunctions]
104107
const vendor = await safelyVendorNPMSpecifiers({
105108
basePath,

0 commit comments

Comments
 (0)
Please sign in to comment.