Skip to content

Commit 7cdda4f

Browse files
committed
br
1 parent fb49bea commit 7cdda4f

File tree

9 files changed

+688
-59
lines changed

9 files changed

+688
-59
lines changed

src/adapter/adapter.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ import {
1212
import { onBuildComplete as onBuildCompleteForMiddleware } from './build/middleware.js'
1313
import { createNetlifyAdapterContext } from './build/netlify-adapter-context.js'
1414
import { onBuildComplete as onBuildCompleteForPagesAndAppHandlers } from './build/pages-and-app-handlers.js'
15+
import { onBuildComplete as onBuildCompleteForRouting } from './build/routing.js'
1516
import { onBuildComplete as onBuildCompleteForStaticAssets } from './build/static-assets.js'
1617

1718
const adapter: NextAdapter = {
1819
name: 'Netlify',
1920
modifyConfig(config) {
2021
if (config.output !== 'export') {
21-
// Enable Next.js standalone mode at build time
22-
config.output = 'standalone'
22+
// If not export, make sure to not build standalone output as it will become useless
23+
// @ts-expect-error types don't unsetting output to not use 'standalone'
24+
config.output = undefined
2325
}
2426

2527
modifyConfigForImageCDN(config)
@@ -31,8 +33,6 @@ const adapter: NextAdapter = {
3133
await writeFile('./onBuildComplete.json', JSON.stringify(nextAdapterContext, null, 2))
3234
// debugger
3335

34-
console.log('onBuildComplete hook called')
35-
3636
const netlifyAdapterContext = createNetlifyAdapterContext(nextAdapterContext)
3737

3838
await onBuildCompleteForImageCDN(nextAdapterContext, netlifyAdapterContext)
@@ -41,6 +41,7 @@ const adapter: NextAdapter = {
4141
// TODO: verifyNetlifyForms
4242
await onBuildCompleteForHeaders(nextAdapterContext, netlifyAdapterContext)
4343
await onBuildCompleteForPagesAndAppHandlers(nextAdapterContext, netlifyAdapterContext)
44+
await onBuildCompleteForRouting(nextAdapterContext, netlifyAdapterContext)
4445

4546
if (netlifyAdapterContext.frameworksAPIConfig) {
4647
// write out config if there is any

src/adapter/build/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ export const NETLIFY_FRAMEWORKS_API_FUNCTIONS = '.netlify/v1/functions'
1515
export const NEXT_RUNTIME_STATIC_ASSETS = '.netlify/static'
1616

1717
export const DISPLAY_NAME_MIDDLEWARE = 'Next.js Middleware Handler'
18+
export const DISPLAY_NAME_ROUTING = 'Next.js Routing Handler'
1819
export const DISPLAY_NAME_PAGES_AND_APP = 'Next.js Pages and App Router Handler'

src/adapter/build/middleware.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ const MIDDLEWARE_FUNCTION_DIR = join(
2121

2222
export async function onBuildComplete(
2323
nextAdapterContext: OnBuildCompleteContext,
24-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
25-
_netlifyAdapterContext: NetlifyAdapterContext,
24+
netlifyAdapterContext: NetlifyAdapterContext,
2625
) {
2726
const { middleware } = nextAdapterContext.outputs
2827
if (!middleware) {
@@ -36,6 +35,8 @@ export async function onBuildComplete(
3635
}
3736

3837
await writeHandlerFile(middleware, nextAdapterContext.config)
38+
39+
netlifyAdapterContext.preparedOutputs.middleware = true
3940
}
4041

4142
const copyHandlerDependenciesForEdgeMiddleware = async (
@@ -186,7 +187,7 @@ const writeHandlerFile = async (
186187
// compatibility layer mentioned above.
187188
await writeFile(
188189
join(MIDDLEWARE_FUNCTION_DIR, `middleware.js`),
189-
`
190+
/* javascript */ `
190191
import { init as htmlRewriterInit } from './edge-runtime/vendor/deno.land/x/htmlrewriter@v1.0.0/src/index.ts'
191192
import { handleMiddleware } from './edge-runtime/middleware.ts';
192193
import handler from './concatenated-file.js';

src/adapter/build/netlify-adapter-context.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import type { FrameworksAPIConfig, OnBuildCompleteContext } from './types.js'
55

66
export function createNetlifyAdapterContext(nextAdapterContext: OnBuildCompleteContext) {
77
let buildId: string | undefined
8-
let frameworksAPIConfig: FrameworksAPIConfig | undefined
98

109
return {
1110
async getBuildId() {
@@ -14,6 +13,11 @@ export function createNetlifyAdapterContext(nextAdapterContext: OnBuildCompleteC
1413
}
1514
return buildId
1615
},
17-
frameworksAPIConfig,
16+
frameworksAPIConfig: undefined as FrameworksAPIConfig | undefined,
17+
preparedOutputs: {
18+
staticAssets: [] as string[],
19+
endpoints: [] as string[],
20+
middleware: false,
21+
},
1822
}
1923
}

src/adapter/build/pages-and-app-handlers.ts

Lines changed: 33 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ const PAGES_AND_APP_FUNCTION_DIR = join(
2222

2323
export async function onBuildComplete(
2424
nextAdapterContext: OnBuildCompleteContext,
25-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
26-
_netlifyAdapterContext: NetlifyAdapterContext,
25+
netlifyAdapterContext: NetlifyAdapterContext,
2726
) {
2827
const requiredFiles = new Set<string>()
2928
const pathnameToEntry: Record<string, string> = {}
@@ -66,68 +65,55 @@ export async function onBuildComplete(
6665

6766
await copyRuntime(join(PAGES_AND_APP_FUNCTION_DIR, RUNTIME_DIR))
6867

68+
const functionsPaths = Object.keys(pathnameToEntry)
69+
6970
// generate needed runtime files
7071
const entrypoint = /* javascript */ `
71-
import { AsyncLocalStorage } from 'node:async_hooks'
72-
import { createRequire } from 'node:module'
73-
import { runNextHandler } from './${RUNTIME_DIR}/dist/adapter/run/pages-and-app-handler.js'
72+
import { AsyncLocalStorage } from 'node:async_hooks'
73+
import { createRequire } from 'node:module'
74+
import { runNextHandler } from './${RUNTIME_DIR}/dist/adapter/run/pages-and-app-handler.js'
7475
75-
globalThis.AsyncLocalStorage = AsyncLocalStorage
76+
globalThis.AsyncLocalStorage = AsyncLocalStorage
7677
77-
const require = createRequire(import.meta.url)
78+
const require = createRequire(import.meta.url)
7879
79-
const pathnameToEntry = ${JSON.stringify(pathnameToEntry, null, 2)}
80+
const pathnameToEntry = ${JSON.stringify(pathnameToEntry, null, 2)}
8081
81-
export default async function handler(request, context) {
82-
const url = new URL(request.url)
82+
export default async function handler(request, context) {
83+
const url = new URL(request.url)
8384
84-
const entry = pathnameToEntry[url.pathname]
85-
if (!entry) {
86-
return new Response('Not Found', { status: 404 })
87-
}
85+
const entry = pathnameToEntry[url.pathname]
86+
if (!entry) {
87+
return new Response('Not Found', { status: 404 })
88+
}
8889
89-
const nextHandler = require('./' + entry).handler
90+
const nextHandler = require('./' + entry).handler
9091
91-
return runNextHandler(request, context, nextHandler)
92-
}
92+
return runNextHandler(request, context, nextHandler)
93+
}
9394
94-
export const config = {
95-
96-
path: ${JSON.stringify(Object.keys(pathnameToEntry), null, 2)},
97-
}
95+
export const config = {
96+
97+
path: ${JSON.stringify(functionsPaths, null, 2)},
98+
}
9899
`
99100
await writeFile(
100101
join(PAGES_AND_APP_FUNCTION_DIR, `${PAGES_AND_APP_FUNCTION_INTERNAL_NAME}.mjs`),
101102
entrypoint,
102103
)
103104

104105
// configuration
105-
// TODO: ideally allow to set `includedFilesBasePath` via frameworks api config
106-
// frameworksAPIConfig.functions ??= { '*': {} }
107-
// frameworksAPIConfig.functions[PAGES_AND_APP_FUNCTION_INTERNAL_NAME] = {
108-
// node_bundler: 'none',
109-
// included_files: ['**'],
110-
// // we can't define includedFilesBasePath via Frameworks API
111-
// // included_files_base_path: PAGES_AND_APP_FUNCTION_DIR,
112-
// }
113-
114-
// not using frameworks api because ... it doesn't allow to set includedFilesBasePath
115-
await writeFile(
116-
join(PAGES_AND_APP_FUNCTION_DIR, `${PAGES_AND_APP_FUNCTION_INTERNAL_NAME}.json`),
117-
JSON.stringify(
118-
{
119-
config: {
120-
name: DISPLAY_NAME_PAGES_AND_APP,
121-
generator: GENERATOR,
122-
node_bundler: 'none',
123-
included_files: ['**'],
124-
includedFilesBasePath: PAGES_AND_APP_FUNCTION_DIR,
125-
},
126-
},
127-
null,
128-
2,
129-
),
130-
)
106+
netlifyAdapterContext.frameworksAPIConfig ??= {}
107+
netlifyAdapterContext.frameworksAPIConfig.functions ??= { '*': {} }
108+
netlifyAdapterContext.frameworksAPIConfig.functions[PAGES_AND_APP_FUNCTION_INTERNAL_NAME] = {
109+
node_bundler: 'none',
110+
included_files: ['**'],
111+
// TODO(pieh): allow to set `includedFilesBasePath` via frameworks api config
112+
// @ts-expect-error we can't define includedFilesBasePath via Frameworks API, this only works because of local monkey patching of CLI
113+
included_files_base_path: PAGES_AND_APP_FUNCTION_DIR,
114+
}
115+
116+
netlifyAdapterContext.preparedOutputs.endpoints.push(...functionsPaths)
131117
}
132118

133119
const copyRuntime = async (handlerDirectory: string): Promise<void> => {

0 commit comments

Comments
 (0)