-
Notifications
You must be signed in to change notification settings - Fork 88
fix: resolve next-server from next app directory and not from plugin #2059
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
8d8d8ae
e7ae048
15c1bdd
4b64c17
1933824
e06157d
ffae6a2
d50c047
c5a4afd
48468bc
33c28ae
be8bc6e
caef767
56aa4f7
1e48952
22e2fa2
6e229c9
74ab70e
e4fadf4
1774f47
bbff3a9
ade1a2e
610d73f
917d3ce
1b01485
04f3164
92dcf3a
66a9670
6e4d78a
8f71783
9efa6cb
a92dbac
767dca9
40c6469
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ import { getHandler } from '../templates/getHandler' | |
import { getResolverForPages, getResolverForSourceFiles } from '../templates/getPageResolver' | ||
|
||
import { ApiConfig, ApiRouteType, extractConfigFromFile, isEdgeConfig } from './analysis' | ||
import { getSourceFileForPage } from './files' | ||
import { getNextServerModulePath, getSourceFileForPage } from './files' | ||
import { writeFunctionConfiguration } from './functionsMetaData' | ||
import { getFunctionNameForPage } from './utils' | ||
|
||
|
@@ -41,6 +41,11 @@ export const generateFunctions = async ( | |
const functionDir = join(functionsDir, HANDLER_FUNCTION_NAME) | ||
const publishDir = relative(functionDir, publish) | ||
|
||
const nextServerModuleAbsoluteLocation = getNextServerModulePath(appDir) | ||
const nextServerModuleRelativeLocation = nextServerModuleAbsoluteLocation | ||
? relative(functionDir, nextServerModuleAbsoluteLocation) | ||
: undefined | ||
|
||
Comment on lines
+46
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if |
||
for (const { route, config, compiled } of apiRoutes) { | ||
// Don't write a lambda if the runtime is edge | ||
if (isEdgeConfig(config.runtime)) { | ||
|
@@ -51,6 +56,7 @@ export const generateFunctions = async ( | |
config, | ||
publishDir, | ||
appDir: relative(functionDir, appDir), | ||
nextServerModuleRelativeLocation, | ||
}) | ||
const functionName = getFunctionNameForPage(route, config.type === ApiRouteType.BACKGROUND) | ||
await ensureDir(join(functionsDir, functionName)) | ||
|
@@ -80,7 +86,12 @@ export const generateFunctions = async ( | |
} | ||
|
||
const writeHandler = async (functionName: string, functionTitle: string, isODB: boolean) => { | ||
const handlerSource = await getHandler({ isODB, publishDir, appDir: relative(functionDir, appDir) }) | ||
const handlerSource = await getHandler({ | ||
isODB, | ||
publishDir, | ||
appDir: relative(functionDir, appDir), | ||
nextServerModuleRelativeLocation, | ||
}) | ||
await ensureDir(join(functionsDir, functionName)) | ||
|
||
// write main handler file (standard or ODB) | ||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -17,16 +17,16 @@ const { URLSearchParams, URL } = require('url') | |||||||
|
||||||||
const { Bridge } = require('@vercel/node-bridge/bridge') | ||||||||
|
||||||||
const { getMultiValueHeaders, getNextServer } = require('./handlerUtils') | ||||||||
const { getMultiValueHeaders } = require('./handlerUtils') | ||||||||
/* eslint-enable @typescript-eslint/no-var-requires */ | ||||||||
|
||||||||
type Mutable<T> = { | ||||||||
-readonly [K in keyof T]: T[K] | ||||||||
} | ||||||||
|
||||||||
// We return a function and then call `toString()` on it to serialise it as the launcher function | ||||||||
|
||||||||
const makeHandler = (conf: NextConfig, app, pageRoot, page) => { | ||||||||
// eslint-disable-next-line max-params | ||||||||
const makeHandler = (conf: NextConfig, app, pageRoot, page, NextServer: NextServerType) => { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since another parameter is being added, consider converting the parameters to one parameter object.
Suggested change
and update at the call sites. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done in 610d73f |
||||||||
// Change working directory into the site root, unless using Nx, which moves the | ||||||||
// dist directory and handles this itself | ||||||||
const dir = path.resolve(__dirname, app) | ||||||||
|
@@ -64,7 +64,6 @@ const makeHandler = (conf: NextConfig, app, pageRoot, page) => { | |||||||
const url = event.rawUrl ? new URL(event.rawUrl) : new URL(path, process.env.URL || 'http://n') | ||||||||
const port = Number.parseInt(url.port) || 80 | ||||||||
|
||||||||
const NextServer: NextServerType = getNextServer() | ||||||||
const nextServer = new NextServer({ | ||||||||
conf, | ||||||||
dir, | ||||||||
|
@@ -118,18 +117,23 @@ export const getApiHandler = ({ | |||||||
config, | ||||||||
publishDir = '../../../.next', | ||||||||
appDir = '../../..', | ||||||||
nextServerModuleRelativeLocation, | ||||||||
}: { | ||||||||
page: string | ||||||||
config: ApiConfig | ||||||||
publishDir?: string | ||||||||
appDir?: string | ||||||||
}): string => | ||||||||
// This is a string, but if you have the right editor plugin it should format as js | ||||||||
javascript/* javascript */ ` | ||||||||
nextServerModuleRelativeLocation: string | undefined | ||||||||
}): string => javascript/* javascript */ ` | ||||||||
if (!${JSON.stringify(nextServerModuleRelativeLocation)}) { | ||||||||
throw new Error('Could not find Next.js server') | ||||||||
} | ||||||||
|
||||||||
const { Server } = require("http"); | ||||||||
// We copy the file here rather than requiring from the node module | ||||||||
const { Bridge } = require("./bridge"); | ||||||||
const { getMultiValueHeaders, getNextServer } = require('./handlerUtils') | ||||||||
const { getMultiValueHeaders } = require('./handlerUtils') | ||||||||
const NextServer = require(${JSON.stringify(nextServerModuleRelativeLocation)}).default | ||||||||
|
||||||||
${config.type === ApiRouteType.SCHEDULED ? `const { schedule } = require("@netlify/functions")` : ''} | ||||||||
|
||||||||
|
@@ -138,7 +142,7 @@ export const getApiHandler = ({ | |||||||
let staticManifest | ||||||||
const path = require("path"); | ||||||||
const pageRoot = path.resolve(path.join(__dirname, "${publishDir}", "server")); | ||||||||
const handler = (${makeHandler.toString()})(config, "${appDir}", pageRoot, ${JSON.stringify(page)}) | ||||||||
const handler = (${makeHandler.toString()})(config, "${appDir}", pageRoot, ${JSON.stringify(page)}, NextServer) | ||||||||
exports.handler = ${ | ||||||||
config.type === ApiRouteType.SCHEDULED ? `schedule(${JSON.stringify(config.schedule)}, handler);` : 'handler' | ||||||||
} | ||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,9 @@ import { outdent as javascript } from 'outdent' | |
|
||
import type { NextConfig } from '../helpers/config' | ||
|
||
import { NextServerType } from './handlerUtils' | ||
import type { NetlifyNextServerType } from './server' | ||
|
||
/* eslint-disable @typescript-eslint/no-var-requires */ | ||
const { promises } = require('fs') | ||
const { Server } = require('http') | ||
|
@@ -21,16 +24,24 @@ const { | |
getPrefetchResponse, | ||
normalizePath, | ||
} = require('./handlerUtils') | ||
const { NetlifyNextServer } = require('./server') | ||
const { getNetlifyNextServer } = require('./server') | ||
/* eslint-enable @typescript-eslint/no-var-requires */ | ||
|
||
type Mutable<T> = { | ||
-readonly [K in keyof T]: T[K] | ||
} | ||
|
||
// We return a function and then call `toString()` on it to serialise it as the launcher function | ||
// eslint-disable-next-line max-params, max-lines-per-function | ||
const makeHandler = (conf: NextConfig, app, pageRoot, staticManifest: Array<[string, string]> = [], mode = 'ssr') => { | ||
// eslint-disable-next-line max-lines-per-function | ||
const makeHandler = ( | ||
conf: NextConfig, | ||
app: string, | ||
pageRoot, | ||
NextServer: NextServerType, | ||
staticManifest: Array<[string, string]> = [], | ||
mode = 'ssr', | ||
// eslint-disable-next-line max-params | ||
) => { | ||
// Change working directory into the site root, unless using Nx, which moves the | ||
// dist directory and handles this itself | ||
const dir = path.resolve(__dirname, app) | ||
|
@@ -44,6 +55,8 @@ const makeHandler = (conf: NextConfig, app, pageRoot, staticManifest: Array<[str | |
require.resolve('./pages.js') | ||
} catch {} | ||
|
||
const NetlifyNextServer: NetlifyNextServerType = getNetlifyNextServer(NextServer) | ||
|
||
const ONE_YEAR_IN_SECONDS = 31536000 | ||
|
||
// React assumes you want development mode if NODE_ENV is unset. | ||
|
@@ -86,7 +99,7 @@ const makeHandler = (conf: NextConfig, app, pageRoot, staticManifest: Array<[str | |
port, | ||
}, | ||
{ | ||
revalidateToken: customContext.odb_refresh_hooks, | ||
revalidateToken: customContext?.odb_refresh_hooks, | ||
pieh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
) | ||
const requestHandler = nextServer.getRequestHandler() | ||
|
@@ -177,15 +190,23 @@ const makeHandler = (conf: NextConfig, app, pageRoot, staticManifest: Array<[str | |
} | ||
} | ||
|
||
export const getHandler = ({ isODB = false, publishDir = '../../../.next', appDir = '../../..' }): string => | ||
// This is a string, but if you have the right editor plugin it should format as js | ||
javascript/* javascript */ ` | ||
export const getHandler = ({ | ||
isODB = false, | ||
publishDir = '../../../.next', | ||
appDir = '../../..', | ||
nextServerModuleRelativeLocation, | ||
}): string => javascript/* javascript */ ` | ||
if (!${JSON.stringify(nextServerModuleRelativeLocation)}) { | ||
throw new Error('Could not find Next.js server') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In current state of this PR, this is thrown on lambda invocation and not during the build, so it restores the that behavior prior to #1950 on when the error is thrown - not the hill I will die on and I can move it back to build time. The other changes in this PR make it more likely to find Without that move, builds for fully static sites that hit current error are just blocked until we implement logic to determine wether we need page route handlers at all and skip it altogether if not needed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, i think that makes sense tbh. We only need the server at runtime so let's go with this. |
||
} | ||
|
||
const { Server } = require("http"); | ||
const { promises } = require("fs"); | ||
// We copy the file here rather than requiring from the node module | ||
const { Bridge } = require("./bridge"); | ||
const { augmentFsModule, getMaxAge, getMultiValueHeaders, getPrefetchResponse, getNextServer, normalizePath } = require('./handlerUtils') | ||
const { NetlifyNextServer } = require('./server') | ||
const { augmentFsModule, getMaxAge, getMultiValueHeaders, getPrefetchResponse, normalizePath } = require('./handlerUtils') | ||
const { getNetlifyNextServer } = require('./server') | ||
const NextServer = require(${JSON.stringify(nextServerModuleRelativeLocation)}).default | ||
|
||
${isODB ? `const { builder } = require("@netlify/functions")` : ''} | ||
const { config } = require("${publishDir}/required-server-files.json") | ||
|
@@ -197,7 +218,7 @@ export const getHandler = ({ isODB = false, publishDir = '../../../.next', appDi | |
const pageRoot = path.resolve(path.join(__dirname, "${publishDir}", "server")); | ||
exports.handler = ${ | ||
isODB | ||
? `builder((${makeHandler.toString()})(config, "${appDir}", pageRoot, staticManifest, 'odb'));` | ||
: `(${makeHandler.toString()})(config, "${appDir}", pageRoot, staticManifest, 'ssr');` | ||
? `builder((${makeHandler.toString()})(config, "${appDir}", pageRoot, NextServer, staticManifest, 'odb'));` | ||
: `(${makeHandler.toString()})(config, "${appDir}", pageRoot, NextServer, staticManifest, 'ssr');` | ||
} | ||
` |
Uh oh!
There was an error while loading. Please reload this page.