* fix(config): recognize next.config.mts and interop CJS imports in config
The next.config.ts loader did not recognize next.config.mts and did not
interop CJS imports (.cjs/.cts/.js/.ts files that assign to module.exports)
brought in by the config file. As a result, fixtures from the Next.js
test/e2e/app-dir/next-config-ts-native-mts/ family failed with either
"Cannot find next.config.*" (silent null return) or "module is not
defined" inside Vite's ESM-only module runner.
Two changes:
1) The loader's local CONFIG_FILES list is extended to include
next.config.mts (matching the canonical list in shims/constants.ts,
which already mirrors Next.js packages/next/src/shared/lib/constants.ts)
while keeping .cjs for backwards-compat with existing vinext users.
deploy.ts and check.ts pick up the same extended list so their config
scanners stay in sync.
2) A new Vite plugin (cjsImportsInteropPlugin) is installed on the inline
runnerImport instance. It wraps .cjs/.cts files (and .js/.ts files that
statically assign to module.exports) so that module.exports becomes the
ESM default export, mirroring how Next.js's SWC pipeline auto-converts
CJS imports from inside next.config.ts. The transform is scoped to the
config-load instance only, so it never affects the user's application
module graph.
Tests ported from .nextjs-ref/test/e2e/app-dir/next-config-ts-native-mts/
{nested-imports,import-js-extensions-cjs,import-js-extensions-esm,
import-from-node-modules}/.
* docs(config): clarify CJS exports/module.exports semantics in comment
The previous comment said "Named exports off module.exports are also
reflected", which glosses over the asymmetric behaviour that Node CJS
modules exhibit when user code does `module.exports = X` followed by
`exports.foo = Y`: the latter writes to the discarded original object
and does not show up on the final default export. Rewrite the comment to
spell out the aliasing, the reassignment break, and the
`module.exports.foo` workaround.
* refactor(config): reuse vite-plugin-commonjs for next.config sibling imports
The hand-rolled cjsImportsInteropPlugin duplicated logic that vinext
already pulls in via vite-plugin-commonjs (used globally for application
code in packages/vinext/src/index.ts:795). Drop the bespoke plugin and
install commonjs() on the inline runnerImport instance instead.
Two pieces of configuration are needed for parity with the previous
behaviour:
1. resolve.extensions explicitly includes .cjs and .cts. vite-plugin-commonjs
keys its 'should I transform this id?' check off config.resolve.extensions,
and Vite's default list (.mjs/.js/.mts/.ts/.jsx/.tsx/.json) omits both
CJS-only extensions. Without this, .cjs/.cts imports flowed through
the runner untransformed and still crashed with 'module is not defined'.
2. A filter that:
- Returns false for the config file itself, so cjsGlobalsInjectorPlugin
remains the sole producer of the file's module wrapper (otherwise
both plugins inject 'module = …' and the runner trips on
'Identifier module has already been declared').
- Returns true for ids under node_modules, so bare-import packages
imported by next.config.* (CJS plugin wrappers, etc.) get transformed.
vite-plugin-commonjs defaults to skipping node_modules.
Net diff: -59 lines, all four next-config-extensions tests still pass,
no regression on tests/next-config.test.ts (108 passing) or the broader
deploy/features/shims/check suites (1637 passing in aggregate).