Skip to content

Commit ff5ee51

Browse files
committed
fix: fail build/deploy when using unsupported Node.js Midleware
1 parent e7318fd commit ff5ee51

File tree

7 files changed

+89
-0
lines changed

7 files changed

+89
-0
lines changed

src/build/content/server.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { trace } from '@opentelemetry/api'
1717
import { wrapTracer } from '@opentelemetry/api/experimental'
1818
import glob from 'fast-glob'
1919
import type { MiddlewareManifest } from 'next/dist/build/webpack/plugins/middleware-plugin.js'
20+
import type { FunctionsConfigManifest } from 'next-with-cache-handler-v2/dist/build/index.js'
2021
import { prerelease, satisfies, lt as semverLowerThan, lte as semverLowerThanOrEqual } from 'semver'
2122

2223
import type { RunConfig } from '../../run/config.js'
@@ -131,6 +132,10 @@ export const copyNextServerCode = async (ctx: PluginContext): Promise<void> => {
131132
return
132133
}
133134

135+
if (path === 'server/functions-config-manifest.json') {
136+
await verifyFunctionsConfigManifest(join(srcDir, path))
137+
}
138+
134139
await cp(srcPath, destPath, { recursive: true, force: true })
135140
}),
136141
)
@@ -376,6 +381,19 @@ const replaceMiddlewareManifest = async (sourcePath: string, destPath: string) =
376381
await writeFile(destPath, newData)
377382
}
378383

384+
const verifyFunctionsConfigManifest = async (sourcePath: string) => {
385+
const data = await readFile(sourcePath, 'utf8')
386+
const manifest = JSON.parse(data) as FunctionsConfigManifest
387+
388+
// https://github.com/vercel/next.js/blob/8367faedd61501025299e92d43a28393c7bb50e2/packages/next/src/build/index.ts#L2465
389+
// Node.js Middleware has hardcoded /_middleware path
390+
if (manifest.functions['/_middleware']) {
391+
throw new Error(
392+
'Only Edge Runtime Middleware is supported. Node.js Middleware is not supported.',
393+
)
394+
}
395+
}
396+
379397
export const verifyHandlerDirStructure = async (ctx: PluginContext) => {
380398
const { nextConfig } = JSON.parse(
381399
await readFile(join(ctx.serverHandlerDir, RUN_CONFIG_FILE), 'utf-8'),
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export const metadata = {
2+
title: 'Simple Next App',
3+
description: 'Description for Simple Next App',
4+
}
5+
6+
export default function RootLayout({ children }) {
7+
return (
8+
<html lang="en">
9+
<body>{children}</body>
10+
</html>
11+
)
12+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function Home() {
2+
return (
3+
<main>
4+
<h1>Home</h1>
5+
</main>
6+
)
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { NextRequest } from 'next/server'
2+
3+
export async function middleware(request: NextRequest) {
4+
console.log('Node.js Middleware request:', request.method, request.nextUrl.pathname)
5+
}
6+
7+
export const config = {
8+
runtime: 'nodejs',
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/** @type {import('next').NextConfig} */
2+
const nextConfig = {
3+
output: 'standalone',
4+
eslint: {
5+
ignoreDuringBuilds: true,
6+
},
7+
experimental: {
8+
nodeMiddleware: true,
9+
},
10+
}
11+
12+
module.exports = nextConfig
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "middleware-node",
3+
"version": "0.1.0",
4+
"private": true,
5+
"scripts": {
6+
"postinstall": "next build",
7+
"dev": "next dev",
8+
"build": "next build"
9+
},
10+
"dependencies": {
11+
"next": "latest",
12+
"react": "18.2.0",
13+
"react-dom": "18.2.0"
14+
},
15+
"test": {
16+
"dependencies": {
17+
"next": ">=15.2.0"
18+
}
19+
}
20+
}

tests/integration/edge-handler.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { type FixtureTestContext } from '../utils/contexts.js'
44
import { createFixture, invokeEdgeFunction, runPlugin } from '../utils/fixture.js'
55
import { generateRandomObjectID, startMockBlobStore } from '../utils/helpers.js'
66
import { LocalServer } from '../utils/local-server.js'
7+
import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs'
78

89
beforeEach<FixtureTestContext>(async (ctx) => {
910
// set for each test a new deployID and siteID
@@ -626,3 +627,13 @@ describe('page router', () => {
626627
expect(bodyFr.nextUrlLocale).toBe('fr')
627628
})
628629
})
630+
631+
test.skipIf(!nextVersionSatisfies('>=15.2.0'))<FixtureTestContext>(
632+
'should throw an Not Supported error when node middleware is used',
633+
async (ctx) => {
634+
await createFixture('middleware-node', ctx)
635+
await expect(runPlugin(ctx)).rejects.toThrow(
636+
'Only Edge Runtime Middleware is supported. Node.js Middleware is not supported.',
637+
)
638+
},
639+
)

0 commit comments

Comments
 (0)