From dff6e13e6cc2b3d254086abadef3965f0fa96740 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Wed, 2 Sep 2026 11:42:39 +0200 Subject: [PATCH] test(v10/e2e): Test Next.js Cloudflare bundle has no orchestrion bundler plugins --- .../tests/worker-bundle.test.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-16-cf-workers/tests/worker-bundle.test.ts diff --git a/dev-packages/e2e-tests/test-applications/nextjs-16-cf-workers/tests/worker-bundle.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-16-cf-workers/tests/worker-bundle.test.ts new file mode 100644 index 000000000000..31814184db88 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-16-cf-workers/tests/worker-bundle.test.ts @@ -0,0 +1,41 @@ +import { expect, test } from '@playwright/test'; +import * as fs from 'fs'; +import * as path from 'path'; +import { isDevMode } from './isDevMode'; + +/** + * The orchestrion bundler plugins are build-time-only, and their module-scope side effects break + * on Workers (an unawaited `WebAssembly.compile()` crashed every cold start, issue #22794). The + * worker bundle OpenNext produces must therefore never contain them: importing `@sentry/nextjs` + * on the server has to keep the plugin graph out of the deployed artifact. + */ +test('worker bundle does not contain the orchestrion bundler plugins', () => { + test.skip(isDevMode, 'requires the production worker build'); + + const openNextDir = path.resolve(__dirname, '..', '.open-next'); + expect(fs.existsSync(path.join(openNextDir, 'worker.js'))).toBe(true); + + // `assets` holds the static client files; everything else is code the worker can run. + const serverFiles = collectJsFiles(openNextDir).filter( + filePath => !filePath.startsWith(path.join(openNextDir, 'assets')), + ); + expect(serverFiles.length).toBeGreaterThan(0); + + const markers = ['code-transformer-bundler-plugins', '__codeTransformerWebpackDiagnostics']; + const leaks = serverFiles.filter(filePath => { + const content = fs.readFileSync(filePath, 'utf8'); + return markers.some(marker => content.includes(marker)); + }); + + expect(leaks.map(filePath => path.relative(openNextDir, filePath))).toEqual([]); +}); + +function collectJsFiles(dir: string): string[] { + return fs.readdirSync(dir, { withFileTypes: true }).flatMap(entry => { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + return collectJsFiles(fullPath); + } + return /\.(js|mjs|cjs)$/.test(entry.name) ? [fullPath] : []; + }); +}