|
| 1 | +#!/usr/bin/env node |
| 2 | +'use strict'; |
| 3 | + |
| 4 | +/** |
| 5 | + * CommonJS runtime smoke test — regression guard for #864. |
| 6 | + * |
| 7 | + * The shipped artifact is compiled to CommonJS and `require()`s its dependencies. If a |
| 8 | + * dependency is ESM-only (no `require` export condition), `require()` throws |
| 9 | + * ERR_REQUIRE_ESM and the server crashes at startup before any config is read — exactly |
| 10 | + * how `uuid@14` broke v2.59.1–2.59.3. |
| 11 | + * |
| 12 | + * Node >= 20.19 / >= 22.12 enable `require(ESM)` by default, which silently masks the |
| 13 | + * mismatch — so just requiring the artifact on a modern Node would NOT catch it. We force |
| 14 | + * the strict (pre-`require(ESM)`) loader with `--no-experimental-require-module` so the |
| 15 | + * mismatch surfaces regardless of the runner's Node version. |
| 16 | + * |
| 17 | + * That flag does not exist on older Node (added in v22.0.0, backported to v20.19.0; |
| 18 | + * absent in 18.x and 20.0–20.18). On those versions the strict loader is already the |
| 19 | + * default, so the flag is unnecessary — and passing it would error with `bad option`. We |
| 20 | + * probe for flag support rather than hard-coding the version matrix, so the guard is |
| 21 | + * strict on every supported Node (>=18) instead of depending on which Node happens to run |
| 22 | + * it (the meta-mistake that produced #864). |
| 23 | + */ |
| 24 | + |
| 25 | +const { spawnSync } = require('node:child_process'); |
| 26 | +const path = require('node:path'); |
| 27 | + |
| 28 | +const FLAG = '--no-experimental-require-module'; |
| 29 | +const entry = path.resolve(__dirname, '..', 'dist', 'index.js'); |
| 30 | +const program = |
| 31 | + `require(${JSON.stringify(entry)}); ` + |
| 32 | + `console.log('CJS runtime load OK (node ' + process.versions.node + ')');`; |
| 33 | + |
| 34 | +// Probe: does this Node recognize the strict-loader flag? Run an empty program with it. |
| 35 | +const flagSupported = |
| 36 | + spawnSync(process.execPath, [FLAG, '-e', ''], { stdio: 'ignore' }).status === 0; |
| 37 | + |
| 38 | +const args = flagSupported ? [FLAG, '-e', program] : ['-e', program]; |
| 39 | +const result = spawnSync(process.execPath, args, { stdio: 'inherit' }); |
| 40 | + |
| 41 | +if (result.status !== 0) { |
| 42 | + console.error( |
| 43 | + `\nCJS runtime smoke test FAILED (node ${process.versions.node}, strict loader forced: ${flagSupported}).` |
| 44 | + ); |
| 45 | + console.error( |
| 46 | + 'The compiled dist/ could not be require()d under the CommonJS loader — a shipped ' + |
| 47 | + 'dependency is likely ESM-only. See #864.' |
| 48 | + ); |
| 49 | + process.exit(result.status === null ? 1 : result.status); |
| 50 | +} |
0 commit comments