Skip to content

Commit aab1312

Browse files
tianzhouclaude
andcommitted
Add post-build smoke test to catch CJS-in-ESM bundling errors
Imports each connector chunk from dist/ and verifies no "Dynamic require" errors occur. This catches cases where tsup accidentally bundles CJS driver internals into ESM chunks — the exact bug from #288 that unit/integration tests miss because they run against TypeScript source, not bundled output. Run with: pnpm test:build Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 69287af commit aab1312

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"test": "vitest run",
3131
"test:unit": "vitest run --project unit",
3232
"test:watch": "vitest",
33-
"test:integration": "vitest run --project integration"
33+
"test:integration": "vitest run --project integration",
34+
"test:build": "node scripts/smoke-test-build.mjs"
3435
},
3536
"engines": {
3637
"node": ">=20"

scripts/smoke-test-build.mjs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env node
2+
3+
// Post-build smoke test: verify that the bundled dist/ output can import
4+
// each connector module without "Dynamic require of X is not supported"
5+
// errors. This catches cases where tsup accidentally bundles CJS driver
6+
// internals into ESM chunks.
7+
//
8+
// Run: node scripts/smoke-test-build.mjs
9+
10+
import { readdir } from "node:fs/promises";
11+
import { pathToFileURL } from "node:url";
12+
import { join } from "node:path";
13+
14+
const distDir = join(import.meta.dirname, "..", "dist");
15+
16+
// Find connector chunk files (e.g. postgres-B7YSSZMH.js, mysql-I35IQ2GH.js)
17+
const files = await readdir(distDir);
18+
const connectorFiles = files.filter(
19+
(f) =>
20+
f.endsWith(".js") &&
21+
/^(postgres|mysql|mariadb|sqlite|sqlserver|demo-loader)-/.test(f)
22+
);
23+
24+
if (connectorFiles.length === 0) {
25+
console.error("No connector chunks found in dist/ — was the build run?");
26+
process.exit(1);
27+
}
28+
29+
let passed = 0;
30+
let failed = 0;
31+
32+
for (const file of connectorFiles) {
33+
const url = pathToFileURL(join(distDir, file)).href;
34+
try {
35+
await import(url);
36+
console.log(` OK ${file}`);
37+
passed++;
38+
} catch (err) {
39+
if (err.message?.includes("Dynamic require")) {
40+
console.error(` FAIL ${file}: ${err.message.split("\n")[0]}`);
41+
failed++;
42+
} else if (err.code === "ERR_MODULE_NOT_FOUND") {
43+
// Driver package not installed — expected in CI/minimal installs
44+
console.log(` SKIP ${file} (driver not installed)`);
45+
passed++;
46+
} else {
47+
// Other errors (e.g. missing config) are fine — we only care about
48+
// bundling errors that happen at import time
49+
console.log(` OK ${file} (runtime error ignored: ${err.message?.split("\n")[0]})`);
50+
passed++;
51+
}
52+
}
53+
}
54+
55+
console.log(`\n${passed} passed, ${failed} failed, ${connectorFiles.length} total`);
56+
if (failed > 0) {
57+
process.exit(1);
58+
}

0 commit comments

Comments
 (0)