Skip to content

Commit

Permalink
fix: combine functions from Frameworks API and internal directories (#…
Browse files Browse the repository at this point in the history
…5734)

* fix: combine functions from Frameworks API and internal directories

* chore: fix test
  • Loading branch information
eduardoboucas authored Jun 24, 2024
1 parent 77980fa commit 9a087b1
Show file tree
Hide file tree
Showing 15 changed files with 125 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ packages/*/lib/
!**/fixtures/**/functions_*/.netlify/edge-functions/manifest.json
!**/fixtures/**/monorepo/**/.netlify
!**/tests/deploy_config/fixtures/**/.netlify
**/plugins/deno-cli

lib
11 changes: 5 additions & 6 deletions packages/build/src/plugins_core/edge_functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,11 @@ const coreStep = async function ({
const distImportMapPath = join(dirname(internalSrcPath), IMPORT_MAP_FILENAME)
const srcPath = srcDirectory ? resolve(buildDir, srcDirectory) : undefined
const frameworksAPISrcPath = resolve(buildDir, packagePath || '', FRAMEWORKS_API_EDGE_FUNCTIONS_ENDPOINT)

let generatedFunctionsPath = internalSrcPath
const generatedFunctionPaths = [internalSrcPath]

if (featureFlags.netlify_build_frameworks_api) {
if (await pathExists(frameworksAPISrcPath)) {
generatedFunctionsPath = frameworksAPISrcPath
generatedFunctionPaths.unshift(frameworksAPISrcPath)
}

const frameworkImportMap = resolve(
Expand All @@ -73,7 +72,7 @@ const coreStep = async function ({
}
}

const sourcePaths = [generatedFunctionsPath, srcPath].filter(Boolean) as string[]
const sourcePaths = [...generatedFunctionPaths, srcPath].filter(Boolean) as string[]

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

Expand All @@ -89,7 +88,7 @@ const coreStep = async function ({
// no-op
}

let vendorDirectory
let vendorDirectory: string | undefined

// If we're building locally, set a vendor directory in `internalSrcPath`.
// This makes Edge Bundler keep the vendor files around after the build,
Expand All @@ -115,7 +114,7 @@ const coreStep = async function ({
importMapPaths,
userLogger: (...args) => log(logs, reduceLogLines(args)),
systemLogger: systemLog,
internalSrcFolder: generatedFunctionsPath,
internalSrcFolder: generatedFunctionPaths,
bootstrapURL: edgeFunctionsBootstrapURL,
vendorDirectory,
})
Expand Down
6 changes: 2 additions & 4 deletions packages/build/src/plugins_core/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,12 @@ const coreStep = async function ({
}
}

const hasFrameworkFunctions = frameworkFunctions.length !== 0

logFunctionsToBundle({
logs,
userFunctions,
userFunctionsSrc: relativeFunctionsSrc,
userFunctionsSrcExists: functionsSrcExists,
internalFunctions: hasFrameworkFunctions ? [] : internalFunctions,
internalFunctions,
internalFunctionsSrc: relativeInternalFunctionsSrc,
frameworkFunctions,
})
Expand All @@ -175,7 +173,7 @@ const coreStep = async function ({
functionsDist,
functionsSrc,
frameworkFunctionsSrc,
internalFunctionsSrc: hasFrameworkFunctions ? undefined : internalFunctionsSrc,
internalFunctionsSrc,
isRunningLocally,
logs,
repositoryRoot,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default async () => new Response("Hello")

export const config = {
excludedPath: "/internal/skip_*",
generator: "Hello",
path: "/internal/*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { greeting } from "greeting"

export default async () => new Response(greeting)

export const config = {
excludedPath: "/framework/skip_*",
generator: "Hello",
path: "/framework/*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"imports": {
"greeting": "./util/greeting.ts"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const greeting = "Hello world"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default async () => new Response('Hello world')

export const config = {
path: "/user"
}
42 changes: 42 additions & 0 deletions packages/build/tests/edge_functions/snapshots/tests.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -787,3 +787,45 @@ Generated by [AVA](https://avajs.dev).
────────────────────────────────────────────────────────────────␊
(Netlify Build completed in 1ms)`

## builds both edge functions generated with the Frameworks API and the ones in the internal directory

> Snapshot 1
`␊
Netlify Build ␊
────────────────────────────────────────────────────────────────␊
> Version␊
@netlify/build 1.0.0␊
> Flags␊
debug: false␊
> Current directory␊
packages/build/tests/edge_functions/fixtures/functions_user_internal_framework␊
> Config file␊
No config file was defined: using default values.␊
> Context␊
production␊
Edge Functions bundling ␊
────────────────────────────────────────────────────────────────␊
Packaging Edge Functions from .netlify/edge-functions directory:␊
- function-3␊
Packaging Edge Functions generated by your framework:␊
- function-2␊
Packaging Edge Functions from netlify/edge-functions directory:␊
- function-1␊
(Edge Functions bundling completed in 1ms)␊
Netlify Build Complete ␊
────────────────────────────────────────────────────────────────␊
(Netlify Build completed in 1ms)`
Binary file modified packages/build/tests/edge_functions/snapshots/tests.js.snap
Binary file not shown.
37 changes: 37 additions & 0 deletions packages/build/tests/edge_functions/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,40 @@ test.serial('builds edge functions generated with the Frameworks API', async (t)
path: '/framework/*',
})
})

test.serial(
'builds both edge functions generated with the Frameworks API and the ones in the internal directory',
async (t) => {
const output = await new Fixture('./fixtures/functions_user_internal_framework')
.withFlags({
debug: false,
featureFlags: { netlify_build_frameworks_api: true },
mode: 'buildbot',
})
.runWithBuild()

t.snapshot(normalizeOutput(output))

const { routes } = await assertManifest(t, 'functions_user_internal_framework')

t.is(routes.length, 3)
t.deepEqual(routes[0], {
function: 'function-2',
pattern: '^/framework(?:/(.*))/?$',
excluded_patterns: ['^/framework/skip_(.*)/?$'],
path: '/framework/*',
})
t.deepEqual(routes[1], {
function: 'function-3',
pattern: '^/internal(?:/(.*))/?$',
excluded_patterns: ['^/internal/skip_(.*)/?$'],
path: '/internal/*',
})
t.deepEqual(routes[2], {
function: 'function-1',
pattern: '^/user/?$',
excluded_patterns: [],
path: '/user',
})
},
)
3 changes: 3 additions & 0 deletions packages/build/tests/functions/snapshots/tests.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,9 @@ Generated by [AVA](https://avajs.dev).
Functions bundling ␊
────────────────────────────────────────────────────────────────␊
Packaging Functions from .netlify/functions-internal directory:␊
- server-internal.mjs␊
Packaging Functions generated by your framework:␊
- server.mjs␊
Expand Down
Binary file modified packages/build/tests/functions/snapshots/tests.js.snap
Binary file not shown.
2 changes: 1 addition & 1 deletion packages/build/tests/functions/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ test('Functions: legacy `.netlify/functions-internal` directory is ignored if th
t.true(functionsDist.includes('manifest.json'))
t.true(functionsDist.includes('server.zip'))
t.true(functionsDist.includes('user.zip'))
t.false(functionsDist.includes('server-internal.zip'))
t.true(functionsDist.includes('server-internal.zip'))

t.snapshot(normalizeOutput(output))
})
Expand Down
11 changes: 7 additions & 4 deletions packages/edge-bundler/node/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { getLogger, LogFunction, Logger } from './logger.js'
import { writeManifest } from './manifest.js'
import { vendorNPMSpecifiers } from './npm_dependencies.js'
import { ensureLatestTypes } from './types.js'
import { nonNullable } from './utils/non_nullable.js'

export interface BundleOptions {
basePath?: string
Expand All @@ -30,7 +31,7 @@ export interface BundleOptions {
distImportMapPath?: string
featureFlags?: FeatureFlags
importMapPaths?: (string | undefined)[]
internalSrcFolder?: string
internalSrcFolder?: string | string[]
onAfterDownload?: OnAfterDownloadHook
onBeforeDownload?: OnBeforeDownloadHook
rootPath?: string
Expand Down Expand Up @@ -92,14 +93,16 @@ export const bundle = async (
// not actually included in the bundle.
const externals = deployConfig.layers.map((layer) => layer.name)

const userSourceDirectories = sourceDirectories.filter((dir) => dir !== internalSrcFolder)
const internalSrcFolders = (Array.isArray(internalSrcFolder) ? internalSrcFolder : [internalSrcFolder]).filter(
nonNullable,
)
const userSourceDirectories = sourceDirectories.filter((dir) => !internalSrcFolders.includes(dir))

const importMap = new ImportMap()

await importMap.addFiles([deployConfig?.importMap, ...importMapPaths], logger)

const userFunctions = userSourceDirectories.length === 0 ? [] : await findFunctions(userSourceDirectories)
const internalFunctions = internalSrcFolder ? await findFunctions([internalSrcFolder]) : []
const internalFunctions = internalSrcFolder ? await findFunctions(internalSrcFolders) : []
const functions = [...internalFunctions, ...userFunctions]
const vendor = await safelyVendorNPMSpecifiers({
basePath,
Expand Down

0 comments on commit 9a087b1

Please sign in to comment.