Skip to content

Commit e01ef29

Browse files
authored
Ensure middleware is output in standalone mode (#32967)
1 parent 5378db8 commit e01ef29

File tree

4 files changed

+67
-21
lines changed

4 files changed

+67
-21
lines changed

packages/next/build/index.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,13 @@ export default async function build(
14001400
'utf8'
14011401
)
14021402

1403+
const middlewareManifest: MiddlewareManifest = JSON.parse(
1404+
await promises.readFile(
1405+
path.join(distDir, SERVER_DIRECTORY, MIDDLEWARE_MANIFEST),
1406+
'utf8'
1407+
)
1408+
)
1409+
14031410
const outputFileTracingRoot =
14041411
config.experimental.outputFileTracingRoot || dir
14051412

@@ -1412,7 +1419,8 @@ export default async function build(
14121419
distDir,
14131420
pageKeys,
14141421
outputFileTracingRoot,
1415-
requiredServerFiles.config
1422+
requiredServerFiles.config,
1423+
middlewareManifest
14161424
)
14171425
})
14181426
}
@@ -1961,13 +1969,6 @@ export default async function build(
19611969
)
19621970
}
19631971

1964-
const middlewareManifest: MiddlewareManifest = JSON.parse(
1965-
await promises.readFile(
1966-
path.join(distDir, SERVER_DIRECTORY, MIDDLEWARE_MANIFEST),
1967-
'utf8'
1968-
)
1969-
)
1970-
19711972
await promises.writeFile(
19721973
path.join(
19731974
distDir,
@@ -2032,7 +2033,8 @@ export default async function build(
20322033
path.relative(outputFileTracingRoot, distDir),
20332034
SERVER_DIRECTORY,
20342035
'pages'
2035-
)
2036+
),
2037+
{ overwrite: true }
20362038
)
20372039
}
20382040

packages/next/build/utils.ts

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
SSG_GET_INITIAL_PROPS_CONFLICT,
1717
SERVER_PROPS_GET_INIT_PROPS_CONFLICT,
1818
SERVER_PROPS_SSG_CONFLICT,
19+
MIDDLEWARE_ROUTE,
1920
} from '../lib/constants'
2021
import prettyBytes from '../lib/pretty-bytes'
2122
import { recursiveReadDir } from '../lib/recursive-readdir'
@@ -40,6 +41,7 @@ import { NextConfigComplete } from '../server/config-shared'
4041
import isError from '../lib/is-error'
4142
import { recursiveDelete } from '../lib/recursive-delete'
4243
import { Sema } from 'next/dist/compiled/async-sema'
44+
import { MiddlewareManifest } from './webpack/plugins/middleware-plugin'
4345

4446
const { builtinModules } = require('module')
4547
const RESERVED_PAGE = /^\/(_app|_error|_document|api(\/|$))/
@@ -1156,7 +1158,8 @@ export async function copyTracedFiles(
11561158
distDir: string,
11571159
pageKeys: string[],
11581160
tracingRoot: string,
1159-
serverConfig: { [key: string]: any }
1161+
serverConfig: { [key: string]: any },
1162+
middlewareManifest: MiddlewareManifest
11601163
) {
11611164
const outputPath = path.join(distDir, 'standalone')
11621165
const copiedFiles = new Set()
@@ -1202,6 +1205,23 @@ export async function copyTracedFiles(
12021205
}
12031206

12041207
for (const page of pageKeys) {
1208+
if (MIDDLEWARE_ROUTE.test(page)) {
1209+
const { files } =
1210+
middlewareManifest.middleware[page.replace(/\/_middleware$/, '')]
1211+
1212+
for (const file of files) {
1213+
const originalPath = path.join(distDir, file)
1214+
const fileOutputPath = path.join(
1215+
outputPath,
1216+
path.relative(tracingRoot, distDir),
1217+
file
1218+
)
1219+
await fs.mkdir(path.dirname(fileOutputPath), { recursive: true })
1220+
await fs.copyFile(originalPath, fileOutputPath)
1221+
}
1222+
continue
1223+
}
1224+
12051225
const pageFile = path.join(
12061226
distDir,
12071227
'server',
@@ -1226,16 +1246,7 @@ const NextServer = require('next/dist/server/next-server').default
12261246
const http = require('http')
12271247
const path = require('path')
12281248
1229-
const nextServer = new NextServer({
1230-
dir: path.join(__dirname),
1231-
dev: false,
1232-
conf: ${JSON.stringify({
1233-
...serverConfig,
1234-
distDir: `./${path.relative(dir, distDir)}`,
1235-
})},
1236-
})
1237-
1238-
const handler = nextServer.getRequestHandler()
1249+
let handler
12391250
12401251
const server = http.createServer(async (req, res) => {
12411252
try {
@@ -1246,12 +1257,26 @@ const server = http.createServer(async (req, res) => {
12461257
res.end('internal server error')
12471258
}
12481259
})
1249-
const currentPort = process.env.PORT || 3000
1260+
const currentPort = parseInt(process.env.PORT, 10) || 3000
1261+
12501262
server.listen(currentPort, (err) => {
12511263
if (err) {
12521264
console.error("Failed to start server", err)
12531265
process.exit(1)
12541266
}
1267+
const addr = server.address()
1268+
const nextServer = new NextServer({
1269+
hostname: 'localhost',
1270+
port: currentPort,
1271+
dir: path.join(__dirname),
1272+
dev: false,
1273+
conf: ${JSON.stringify({
1274+
...serverConfig,
1275+
distDir: `./${path.relative(dir, distDir)}`,
1276+
})},
1277+
})
1278+
handler = nextServer.getRequestHandler()
1279+
12551280
console.log("Listening on port", currentPort)
12561281
})
12571282
`

test/production/required-server-files.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,22 @@ describe('should set-up next', () => {
107107
if (server) await killApp(server)
108108
})
109109

110+
it('should output middleware correctly', async () => {
111+
// the middleware-runtime is located in .next/static/chunks so ensure
112+
// the folder is present
113+
expect(
114+
await fs.pathExists(join(next.testDir, 'standalone/.next/static/chunks'))
115+
).toBe(true)
116+
expect(
117+
await fs.pathExists(
118+
join(
119+
next.testDir,
120+
'standalone/.next/server/pages/middleware/_middleware.js'
121+
)
122+
)
123+
).toBe(true)
124+
})
125+
110126
it('should output required-server-files manifest correctly', async () => {
111127
expect(requiredFilesManifest.version).toBe(1)
112128
expect(Array.isArray(requiredFilesManifest.files)).toBe(true)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export async function middleware(req) {
2+
return new Response('hello from middleware')
3+
}

0 commit comments

Comments
 (0)