fix(rsc/cjs): unwrap default
based on __cjs_module_runner_transform
marker
#905
+37
−14
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
The
cjsModuleRunnerPlugin
was incorrectly transforming CommonJSrequire()
calls by always accessing.default
on the imported module:This assumption fails when Vite's import analysis resolves the import to an ESM variant of a package. For example, when importing
@swc/helpers/_/_interop_require_default
, Vite may resolve it to@swc/helpers/esm/_interop_require_default.js
. Pure ESM modules with only named exports don't have a.default
property, causing.default
to returnundefined
and breaking code that depends on these imports.This issue was discovered when trying to load Next.js CommonJS modules that import from packages like
@swc/helpers
, resulting in errors like:Solution
Introduced a runtime interop helper
__cjs_interop__
that uses an explicit marker-based approach to distinguish transformed CJS modules from genuine ESM modules:All modules transformed by
cjsModuleRunnerPlugin
now export an explicit marker:The helper only unwraps
.default
when the__cjs_module_runner_transform
marker is present, ensuring we don't incorrectly unwrap.default
on genuine ESM modules. This explicit approach is safer and more predictable than heuristic-based detection.Changes
transformCjsToEsm()
to inject the interop helper and wrap all dynamic imports__cjs_module_runner_transform
marker export to all transformed CJS modulesrequire()
callsrequire()
calls are present in the codeTesting
Fixes #904
Original prompt
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.