#4613·nitro

v2 externalization treats ESM-looking CommonJS comments as executable syntax

Author: benpsnyderCreated Sep 12, 2026Updated Sep 12, 2026
Labelsv2

Environment

  • Nitro 2.13.4 (v2 at e6ed0aa35a94e873e2e42487aec149238846225a)
  • mlly 1.8.2; Node 24.15.0; Linux

Minimal reproduction

Create a Node dependency named comment-syntax with package.json:

json
{ "name": "comment-syntax", "version": "1.0.0", "main": "index.js" }

Its index.js is valid CommonJS:

javascript
/* export default example */
module.exports = 42;

Import that dependency from a Nitro server route. Both the default and experimental.legacyExternals resolvers decline to externalize it because isValidNodeImport() counts the comment as ESM syntax by default. Direct Node loading succeeds.

The underlying validator behavior can be checked independently:

javascript
import { createRequire } from "node:module";
import { isValidNodeImport } from "mlly";

const require = createRequire(import.meta.url);
const entry = require.resolve("comment-syntax");
console.log(await isValidNodeImport(entry)); // false
console.log(await isValidNodeImport(entry, { stripComments: true })); // true

Expected behavior

Node externalization should examine executable syntax, ignoring comments while preserving explicit inlining and rejection of real mixed CommonJS/ESM code.

Proposed fix and TypeScript dependency

Pass { stripComments: true } in both v2 externals implementations. Regression tests exercise real CommonJS files with the real validator, preserving explicit inline rules and real mixed-syntax bundling. The two comment cases fail before this change and pass afterward.

This is one part of the TypeScript server-import failure reported in analogjs/analog#2457, currently worked around in analogjs/analog#2548. TypeScript 6.0.3 additionally contains ESM-looking diagnostic strings and identifier prefixes. Those require the separate mlly fix tracked in unjs/mlly#369.

The Nitro change alone is not claimed to fix TypeScript. Combined qualification uses a locally packed mlly build; the final TypeScript fix needs a released mlly version with token-aware detection. Nitro v3 is being qualified separately.