diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 766df924bd9ee..04d908262a1b9 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -1776,9 +1776,12 @@ export default async function build( { filter(item) { // we copy page chunks separately to not copy stale entries - return !item.match(/^[/\\](pages|app)[/\\]/) + return ( + !item.startsWith('/middleware.js') && + !item.match(/^[/\\](pages|app)[/\\]/) + ) }, - overwrite: true, + overwrite: false, } ) } diff --git a/packages/next/src/lib/recursive-copy.ts b/packages/next/src/lib/recursive-copy.ts index 68936115c4cd9..1674e34166f36 100644 --- a/packages/next/src/lib/recursive-copy.ts +++ b/packages/next/src/lib/recursive-copy.ts @@ -66,11 +66,14 @@ export async function recursiveCopy( // we remove the base path (from) and replace \ by / (windows) filter(item.replace(from, '').replace(/\\/g, '/')) ) { - await promises.copyFile( - item, - target, - overwrite ? undefined : COPYFILE_EXCL - ) + await promises + .copyFile(item, target, overwrite ? undefined : COPYFILE_EXCL) + .catch((err) => { + // if overwrite is false we shouldn't fail on EEXIST + if (err.code !== 'EEXIST') { + throw err + } + }) sema.release() } else { sema.release() diff --git a/test/e2e/app-dir/app/flying-shuttle.test.ts b/test/e2e/app-dir/app/flying-shuttle.test.ts index ebe006c0c4bb5..86ad5500bd803 100644 --- a/test/e2e/app-dir/app/flying-shuttle.test.ts +++ b/test/e2e/app-dir/app/flying-shuttle.test.ts @@ -400,5 +400,28 @@ import { nextTestSetup, isNextStart } from 'e2e-utils' await next.patchFile(dataPath, originalDataContent) } }) + + it('should have updated middleware on change', async () => { + await next.stop() + + const dataPath = 'middleware.js' + const originalDataContent = await next.readFile(dataPath) + + try { + await next.patchFile( + dataPath, + originalDataContent.replace( + `'x-flying-shuttle': '1'`, + `'x-flying-shuttle': '2'` + ) + ) + await nextStart() + + const res = await next.fetch('/flying-shuttle') + expect(res.headers.get('x-flying-shuttle')).toBe('2') + } finally { + await next.patchFile(dataPath, originalDataContent) + } + }) } ) diff --git a/test/e2e/app-dir/app/middleware.js b/test/e2e/app-dir/app/middleware.js index 56bc894fc458a..1a233b88bfe14 100644 --- a/test/e2e/app-dir/app/middleware.js +++ b/test/e2e/app-dir/app/middleware.js @@ -6,6 +6,14 @@ import { NextResponse } from 'next/server' * @returns {Promise} */ export async function middleware(request) { + if (request.nextUrl.pathname === '/flying-shuttle') { + return NextResponse.next({ + headers: { + 'x-flying-shuttle': '1', + }, + }) + } + if (request.nextUrl.pathname === '/searchparams-normalization-bug') { const headers = new Headers(request.headers) headers.set('test', request.nextUrl.searchParams.get('val') || '')