Skip to content

Commit a298b3b

Browse files
committed
remove next patching as we don't use that for newer next versions
1 parent 0305db3 commit a298b3b

File tree

4 files changed

+1
-343
lines changed

4 files changed

+1
-343
lines changed

src/build/content/next-shims/telemetry-storage.cts

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/build/content/server.test.ts

Lines changed: 1 addition & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ import { beforeEach, describe, expect, test, vi } from 'vitest'
77
import { mockFileSystem } from '../../../tests/index.js'
88
import { PluginContext, RequiredServerFilesManifest } from '../plugin-context.js'
99

10-
import {
11-
copyNextServerCode,
12-
getPatchesToApply,
13-
NextInternalModuleReplacement,
14-
verifyHandlerDirStructure,
15-
} from './server.js'
10+
import { copyNextServerCode, verifyHandlerDirStructure } from './server.js'
1611

1712
vi.mock('node:fs', async () => {
1813
// eslint-disable-next-line @typescript-eslint/no-explicit-any, unicorn/no-await-expression-member
@@ -272,112 +267,3 @@ describe('verifyHandlerDirStructure', () => {
272267
)
273268
})
274269
})
275-
276-
describe(`getPatchesToApply`, () => {
277-
beforeEach(() => {
278-
delete process.env.NETLIFY_NEXT_FORCE_APPLY_ONGOING_PATCHES
279-
})
280-
test('ongoing: false', () => {
281-
const shouldPatchBeApplied = {
282-
'13.4.1': false, // before supported next version
283-
'13.5.1': true, // first stable supported version
284-
'14.1.4-canary.1': true, // canary version before stable with maxStableVersion - should be applied
285-
'14.1.4': true, // latest stable tested version
286-
'14.2.0': false, // untested stable version
287-
'14.2.0-canary.37': true, // maxVersion, should be applied
288-
'14.2.0-canary.38': false, // not ongoing patch so should not be applied
289-
}
290-
291-
const nextModule = 'test'
292-
293-
const patches: NextInternalModuleReplacement[] = [
294-
{
295-
ongoing: false,
296-
minVersion: '13.5.0-canary.0',
297-
maxVersion: '14.2.0-canary.37',
298-
nextModule,
299-
shimModule: 'not-used-in-test',
300-
},
301-
]
302-
303-
for (const [nextVersion, telemetryShimShouldBeApplied] of Object.entries(
304-
shouldPatchBeApplied,
305-
)) {
306-
const patchesToApply = getPatchesToApply(nextVersion, patches)
307-
const hasTelemetryShim = patchesToApply.some((patch) => patch.nextModule === nextModule)
308-
expect({ nextVersion, apply: hasTelemetryShim }).toEqual({
309-
nextVersion,
310-
apply: telemetryShimShouldBeApplied,
311-
})
312-
}
313-
})
314-
315-
test('ongoing: true', () => {
316-
const shouldPatchBeApplied = {
317-
'13.4.1': false, // before supported next version
318-
'13.5.1': true, // first stable supported version
319-
'14.1.4-canary.1': true, // canary version before stable with maxStableVersion - should be applied
320-
'14.1.4': true, // latest stable tested version
321-
'14.2.0': false, // untested stable version
322-
'14.2.0-canary.38': true, // ongoing patch so should be applied on prerelease versions
323-
}
324-
325-
const nextModule = 'test'
326-
327-
const patches: NextInternalModuleReplacement[] = [
328-
{
329-
ongoing: true,
330-
minVersion: '13.5.0-canary.0',
331-
maxStableVersion: '14.1.4',
332-
nextModule,
333-
shimModule: 'not-used-in-test',
334-
},
335-
]
336-
337-
for (const [nextVersion, telemetryShimShouldBeApplied] of Object.entries(
338-
shouldPatchBeApplied,
339-
)) {
340-
const patchesToApply = getPatchesToApply(nextVersion, patches)
341-
const hasTelemetryShim = patchesToApply.some((patch) => patch.nextModule === nextModule)
342-
expect({ nextVersion, apply: hasTelemetryShim }).toEqual({
343-
nextVersion,
344-
apply: telemetryShimShouldBeApplied,
345-
})
346-
}
347-
})
348-
349-
test('ongoing: true + NETLIFY_NEXT_FORCE_APPLY_ONGOING_PATCHES', () => {
350-
process.env.NETLIFY_NEXT_FORCE_APPLY_ONGOING_PATCHES = 'true'
351-
const shouldPatchBeApplied = {
352-
'13.4.1': false, // before supported next version
353-
'13.5.1': true, // first stable supported version
354-
'14.1.4-canary.1': true, // canary version before stable with maxStableVersion - should be applied
355-
'14.1.4': true, // latest stable tested version
356-
'14.2.0': true, // untested stable version but NETLIFY_NEXT_FORCE_APPLY_ONGOING_PATCHES is used
357-
'14.2.0-canary.38': true, // ongoing patch so should be applied on prerelease versions
358-
}
359-
360-
const nextModule = 'test'
361-
362-
const patches: NextInternalModuleReplacement[] = [
363-
{
364-
ongoing: true,
365-
minVersion: '13.5.0-canary.0',
366-
maxStableVersion: '14.1.4',
367-
nextModule,
368-
shimModule: 'not-used-in-test',
369-
},
370-
]
371-
372-
for (const [nextVersion, telemetryShimShouldBeApplied] of Object.entries(
373-
shouldPatchBeApplied,
374-
)) {
375-
const patchesToApply = getPatchesToApply(nextVersion, patches)
376-
const hasTelemetryShim = patchesToApply.some((patch) => patch.nextModule === nextModule)
377-
expect({ nextVersion, apply: hasTelemetryShim }).toEqual({
378-
nextVersion,
379-
apply: telemetryShimShouldBeApplied,
380-
})
381-
}
382-
})
383-
})

src/build/content/server.ts

Lines changed: 0 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -186,108 +186,6 @@ async function recreateNodeModuleSymlinks(src: string, dest: string, org?: strin
186186
)
187187
}
188188

189-
export type NextInternalModuleReplacement = {
190-
/**
191-
* Minimum Next.js version that this patch should be applied to
192-
*/
193-
minVersion: string
194-
/**
195-
* If the reason to patch was not addressed in Next.js we mark this as ongoing
196-
* to continue to test latest versions to know wether we should bump `maxStableVersion`
197-
*/
198-
ongoing: boolean
199-
/**
200-
* Module that should be replaced
201-
*/
202-
nextModule: string
203-
/**
204-
* Location of replacement module (relative to `<runtime>/dist/build/content`)
205-
*/
206-
shimModule: string
207-
} & (
208-
| {
209-
ongoing: true
210-
/**
211-
* Maximum Next.js version that this patch should be applied to, note that for ongoing patches
212-
* we will continue to apply patch for prerelease versions also as canary versions are released
213-
* very frequently and trying to target canary versions is not practical. If user is using
214-
* canary next versions they should be aware of the risks
215-
*/
216-
maxStableVersion: string
217-
}
218-
| {
219-
ongoing: false
220-
/**
221-
* Maximum Next.js version that this patch should be applied to. This should be last released
222-
* version of Next.js before version making the patch not needed anymore (can be canary version).
223-
*/
224-
maxVersion: string
225-
}
226-
)
227-
228-
const nextInternalModuleReplacements: NextInternalModuleReplacement[] = [
229-
{
230-
// standalone is loading expensive Telemetry module that is not actually used
231-
// so this replace that module with lightweight no-op shim that doesn't load additional modules
232-
// see https://github.com/vercel/next.js/pull/63574 that removed need for this shim
233-
ongoing: false,
234-
minVersion: '13.5.0-canary.0',
235-
// perf released in https://github.com/vercel/next.js/releases/tag/v14.2.0-canary.43
236-
maxVersion: '14.2.0-canary.42',
237-
nextModule: 'next/dist/telemetry/storage.js',
238-
shimModule: './next-shims/telemetry-storage.cjs',
239-
},
240-
]
241-
242-
export function getPatchesToApply(
243-
nextVersion: string,
244-
patches: NextInternalModuleReplacement[] = nextInternalModuleReplacements,
245-
) {
246-
return patches.filter((patch) => {
247-
// don't apply patches for next versions below minVersion
248-
if (semverLowerThan(nextVersion, patch.minVersion)) {
249-
return false
250-
}
251-
252-
if (patch.ongoing) {
253-
// apply ongoing patches when used next version is prerelease or NETLIFY_NEXT_FORCE_APPLY_ONGOING_PATCHES env var is used
254-
if (prerelease(nextVersion) || process.env.NETLIFY_NEXT_FORCE_APPLY_ONGOING_PATCHES) {
255-
return true
256-
}
257-
258-
// apply ongoing patches for stable next versions below or equal maxStableVersion
259-
return semverLowerThanOrEqual(nextVersion, patch.maxStableVersion)
260-
}
261-
262-
// apply patches for next versions below or equal maxVersion
263-
return semverLowerThanOrEqual(nextVersion, patch.maxVersion)
264-
})
265-
}
266-
267-
async function patchNextModules(
268-
ctx: PluginContext,
269-
nextVersion: string,
270-
serverHandlerRequireResolve: NodeRequire['resolve'],
271-
): Promise<void> {
272-
// apply only those patches that target used Next version
273-
const moduleReplacementsToApply = getPatchesToApply(nextVersion)
274-
275-
if (moduleReplacementsToApply.length !== 0) {
276-
await Promise.all(
277-
moduleReplacementsToApply.map(async ({ nextModule, shimModule }) => {
278-
try {
279-
const nextModulePath = serverHandlerRequireResolve(nextModule)
280-
const shimModulePath = posixJoin(ctx.pluginDir, 'dist', 'build', 'content', shimModule)
281-
282-
await cp(shimModulePath, nextModulePath, { force: true })
283-
} catch {
284-
// this is perf optimization, so failing it shouldn't break the build
285-
}
286-
}),
287-
)
288-
}
289-
}
290-
291189
export const copyNextDependencies = async (ctx: PluginContext): Promise<void> => {
292190
await tracer.withActiveSpan('copyNextDependencies', async () => {
293191
const entries = await readdir(ctx.standaloneDir)
@@ -325,10 +223,6 @@ export const copyNextDependencies = async (ctx: PluginContext): Promise<void> =>
325223

326224
const serverHandlerRequire = createRequire(posixJoin(ctx.serverHandlerDir, ':internal:'))
327225

328-
if (ctx.nextVersion) {
329-
await patchNextModules(ctx, ctx.nextVersion, serverHandlerRequire.resolve)
330-
}
331-
332226
// detect if it might lead to a runtime issue and throw an error upfront on build time instead of silently failing during runtime
333227
try {
334228
const nextEntryAbsolutePath = serverHandlerRequire.resolve('next')

tests/integration/simple-app.test.ts

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {
1919
test,
2020
vi,
2121
} from 'vitest'
22-
import { getPatchesToApply } from '../../src/build/content/server.js'
2322
import { type FixtureTestContext } from '../utils/contexts.js'
2423
import {
2524
createFixture,
@@ -434,78 +433,3 @@ test<FixtureTestContext>('can require CJS module that is not bundled', async (ct
434433
expect(parsedBody.notBundledCJSModule.isBundled).toEqual(false)
435434
expect(parsedBody.bundledCJSModule.isBundled).toEqual(true)
436435
})
437-
438-
describe('next patching', async () => {
439-
const { cp: originalCp, appendFile } = (await vi.importActual(
440-
'node:fs/promises',
441-
)) as typeof import('node:fs/promises')
442-
443-
const { version: nextVersion } = createRequire(
444-
`${getFixtureSourceDirectory('simple')}/:internal:`,
445-
)('next/package.json')
446-
447-
beforeAll(() => {
448-
process.env.NETLIFY_NEXT_FORCE_APPLY_ONGOING_PATCHES = 'true'
449-
})
450-
451-
afterAll(() => {
452-
delete process.env.NETLIFY_NEXT_FORCE_APPLY_ONGOING_PATCHES
453-
})
454-
455-
beforeEach(() => {
456-
mockedCp.mockClear()
457-
mockedCp.mockRestore()
458-
})
459-
460-
test<FixtureTestContext>(`expected patches are applied and used (next version: "${nextVersion}")`, async (ctx) => {
461-
const patches = getPatchesToApply(nextVersion)
462-
463-
await createFixture('simple', ctx)
464-
465-
const fieldNamePrefix = `TEST_${Date.now()}`
466-
467-
mockedCp.mockImplementation(async (...args) => {
468-
const returnValue = await originalCp(...args)
469-
if (typeof args[1] === 'string') {
470-
for (const patch of patches) {
471-
if (args[1].includes(join(patch.nextModule))) {
472-
// we append something to assert that patch file was actually used
473-
await appendFile(
474-
args[1],
475-
`;globalThis['${fieldNamePrefix}_${patch.nextModule}'] = 'patched'`,
476-
)
477-
}
478-
}
479-
}
480-
481-
return returnValue
482-
})
483-
484-
await runPlugin(ctx)
485-
486-
// patched files was not used before function invocation
487-
for (const patch of patches) {
488-
expect(globalThis[`${fieldNamePrefix}_${patch.nextModule}`]).not.toBeDefined()
489-
}
490-
491-
const home = await invokeFunction(ctx)
492-
// make sure the function does work
493-
expect(home.statusCode).toBe(200)
494-
expect(load(home.body)('h1').text()).toBe('Home')
495-
496-
let shouldUpdateUpperBoundMessage = ''
497-
498-
// file was used during function invocation
499-
for (const patch of patches) {
500-
expect(globalThis[`${fieldNamePrefix}_${patch.nextModule}`]).toBe('patched')
501-
502-
if (patch.ongoing && !prerelease(nextVersion) && gt(nextVersion, patch.maxStableVersion)) {
503-
shouldUpdateUpperBoundMessage += `Ongoing ${shouldUpdateUpperBoundMessage ? '\n' : ''}"${patch.nextModule}" patch still works on "${nextVersion}" which is higher than currently set maxStableVersion ("${patch.maxStableVersion}"). Update maxStableVersion in "src/build/content/server.ts" for this patch to at least "${nextVersion}".`
504-
}
505-
}
506-
507-
if (shouldUpdateUpperBoundMessage) {
508-
expect.fail(shouldUpdateUpperBoundMessage)
509-
}
510-
})
511-
})

0 commit comments

Comments
 (0)