Skip to content

Commit f44df80

Browse files
authored
test(e2e): Assert Next.js Cloudflare worker bundle stays free of orchestrion bundler plugins (#23910)
Adds one test to the `nextjs-16-cf-workers` e2e app. After the OpenNext build, it scans every script in `.open-next/` (except static assets) and fails if the orchestrion bundler plugins show up, naming the offending files. The plugins are build-time-only, but they used to get compiled into the worker bundle, where an unawaited `WebAssembly.compile()` crashed every cold start. The bundle check is deterministic, unlike waiting for an error to not appear. The below issue is fixed in #23906 already, this PR is just adding the verification. Closes #22794
1 parent c50fcb8 commit f44df80

1 file changed

Lines changed: 41 additions & 0 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { expect, test } from '@playwright/test';
2+
import * as fs from 'fs';
3+
import * as path from 'path';
4+
import { isDevMode } from './isDevMode';
5+
6+
/**
7+
* The orchestrion bundler plugins are build-time-only, and their module-scope side effects break
8+
* on Workers (an unawaited `WebAssembly.compile()` crashed every cold start, issue #22794). The
9+
* worker bundle OpenNext produces must therefore never contain them: importing `@sentry/nextjs`
10+
* on the server has to keep the plugin graph out of the deployed artifact.
11+
*/
12+
test('worker bundle does not contain the orchestrion bundler plugins', () => {
13+
test.skip(isDevMode, 'requires the production worker build');
14+
15+
const openNextDir = path.resolve(__dirname, '..', '.open-next');
16+
expect(fs.existsSync(path.join(openNextDir, 'worker.js'))).toBe(true);
17+
18+
// `assets` holds the static client files; everything else is code the worker can run.
19+
const serverFiles = collectJsFiles(openNextDir).filter(
20+
filePath => !filePath.startsWith(path.join(openNextDir, 'assets')),
21+
);
22+
expect(serverFiles.length).toBeGreaterThan(0);
23+
24+
const markers = ['code-transformer-bundler-plugins', '__codeTransformerWebpackDiagnostics'];
25+
const leaks = serverFiles.filter(filePath => {
26+
const content = fs.readFileSync(filePath, 'utf8');
27+
return markers.some(marker => content.includes(marker));
28+
});
29+
30+
expect(leaks.map(filePath => path.relative(openNextDir, filePath))).toEqual([]);
31+
});
32+
33+
function collectJsFiles(dir: string): string[] {
34+
return fs.readdirSync(dir, { withFileTypes: true }).flatMap(entry => {
35+
const fullPath = path.join(dir, entry.name);
36+
if (entry.isDirectory()) {
37+
return collectJsFiles(fullPath);
38+
}
39+
return /\.(js|mjs|cjs)$/.test(entry.name) ? [fullPath] : [];
40+
});
41+
}

0 commit comments

Comments
 (0)