Skip to content

feat(swc): Make module transforms optional via module feature#11509

Merged
kdy1 merged 4 commits intomainfrom
claude/issue-11505-20260127-0559
Jan 27, 2026
Merged

feat(swc): Make module transforms optional via module feature#11509
kdy1 merged 4 commits intomainfrom
claude/issue-11505-20260127-0559

Conversation

@kdy1
Copy link
Copy Markdown
Member

@kdy1 kdy1 commented Jan 27, 2026

Summary

Make swc_ecma_transforms_module an optional dependency of the swc crate. Bundlers typically handle module transforms themselves, so they don't need this code, reducing binary size.

Changes

  • Add module feature to swc crate that enables module transforms
  • Gate all module-related code with #[cfg(feature = "module")]
  • Add base_module feature to swc_core that enables swc/module
  • Update swc_cli_impl, binding_core_node, and binding_core_wasm to explicitly enable the module feature

Closes #11505

Generated with Claude Code

This change makes `swc_ecma_transforms_module` an optional dependency of
the `swc` crate. Bundlers typically handle module transforms themselves,
so they don't need this code, reducing binary size.

Changes:
- Add `module` feature to `swc` crate that enables module transforms
- Gate all module-related code with `#[cfg(feature = "module")]`
- Add `base_module` feature to `swc_core` that enables `swc/module`
- Update `swc_cli_impl`, `binding_core_node`, and `binding_core_wasm`
  to explicitly enable the module feature

By default, the `swc` crate no longer includes module transforms. Users
who need CommonJS, AMD, UMD, or SystemJS transforms must enable the
`module` feature explicitly.

Closes #11505

Co-Authored-By: Donny/강동윤 <kdy1@users.noreply.github.com>
@kdy1 kdy1 added this to the Planned milestone Jan 27, 2026
@kdy1 kdy1 self-assigned this Jan 27, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Jan 27, 2026

🦋 Changeset detected

Latest commit: ffd4ad3

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jan 27, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ kdy1
❌ github-actions[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

@socket-security
Copy link
Copy Markdown

socket-security bot commented Jan 27, 2026

No dependency changes detected. Learn more about Socket for GitHub.

👍 No dependency changes detected in pull request

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 27, 2026

Binary Sizes

File Size
swc.linux-x64-gnu.node 28M (28661576 bytes)

Commit: 7b0035d

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Jan 27, 2026

Merging this PR will not alter performance

✅ 184 untouched benchmarks


Comparing claude/issue-11505-20260127-0559 (ffd4ad3) with main (d72c9df)

Open in CodSpeed

@kdy1
Copy link
Copy Markdown
Member Author

kdy1 commented Jan 27, 2026

@claude fix ci

@claude

This comment has been minimized.

The Context trait is used in both the module and plugin feature
code paths, so the import needs to be gated by either condition.

Co-authored-by: Donny/강동윤 <kdy1@users.noreply.github.com>
@kdy1 kdy1 marked this pull request as ready for review January 27, 2026 07:00
@kdy1 kdy1 requested review from a team as code owners January 27, 2026 07:00
kodiakhq[bot]
kodiakhq bot previously approved these changes Jan 27, 2026
@claude

This comment has been minimized.

@kdy1
Copy link
Copy Markdown
Member Author

kdy1 commented Jan 27, 2026

@claude fix ci

@claude

This comment has been minimized.

This ensures tests run with module transforms enabled, fixing the babel
exec test failures.

Co-authored-by: Donny/강동윤 <kdy1@users.noreply.github.com>
kodiakhq[bot]
kodiakhq bot previously approved these changes Jan 27, 2026
@claude

This comment has been minimized.

@kdy1 kdy1 merged commit b94a178 into main Jan 27, 2026
19 of 21 checks passed
@kdy1 kdy1 deleted the claude/issue-11505-20260127-0559 branch January 27, 2026 13:27
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Jan 27, 2026

PR Review: Make module transforms optional via module feature

Summary

This PR makes swc_ecma_transforms_module an optional dependency of the swc crate, allowing bundlers that handle their own module transforms to reduce binary size.

Code Quality & Best Practices ✅

Strengths:

  • Clean feature flag organization with clear documentation in comments
  • Proper #[cfg(feature = "module")] gating throughout the codebase
  • Stub implementations allow configuration to still be deserialized even without the feature
  • Good separation - the bindings and CLI explicitly opt-in to the module feature

Suggestions:

  1. Changeset package name: The changeset lists swc_ecma_transforms_module: major, but this change primarily affects the swc crate. Consider adding swc: minor to the changeset since you're adding a new feature, or at minimum document that the major bump is because swc_ecma_transforms_module is now an optional dependency (which may be a breaking change for some consumers).

Potential Issues ⚠️

  1. Silent feature degradation: When the module feature is disabled but a user's config specifies module.type: "commonjs" (or similar), the transform silently becomes a noop. Consider adding a warning or error when module config is provided but the feature is disabled:

    #[cfg(not(feature = "module"))]
    impl ModuleConfig {
        pub fn build<'cmt>(...) -> Box<dyn Pass + 'cmt> {
            // Consider logging a warning here
            // tracing::warn!("Module transform config provided but 'module' feature is disabled");
            Box::new(noop_pass())
        }
    }
  2. Feature flag in #[cfg(not(feature = "module"))] block at line 712-722: The stub module_pass still calls ModuleConfig::build and references rewrite_import_pass. While this works (since both are noops), it adds unnecessary runtime overhead. Consider simplifying to just:

    #[cfg(not(feature = "module"))]
    let module_pass: Box<dyn Pass> = Box::new((
        Optional::new(helpers::inject_helpers(unresolved_mark), inject_helpers),
    ));

Performance Considerations ✅

  • The change achieves its stated goal of reducing binary size for bundlers
  • When the feature is enabled, there should be no performance difference from before
  • When disabled, noop passes have minimal runtime overhead

Security Concerns ✅

No security issues identified. This is a feature-gating change that doesn't introduce new functionality.

Test Coverage ⚠️

  • The code compiles with --no-default-features --features lint,isolated-dts (verified locally)
  • The code compiles with default features (verified locally)
  • Suggestion: Consider adding a CI job that runs tests with the module feature disabled to catch regressions. This could be a simple cargo check with reduced features.

Minor Observations

  1. The let _ = &var; pattern for suppressing unused warnings is functional but could be more idiomatic with #[allow(unused)] on the variables that exist across both feature branches.

  2. Good job ensuring BuiltInput struct has the resolver field conditionally compiled.

Overall Assessment

This is a well-implemented feature flag change. The approach of creating stub types that can still deserialize config is good - it means existing configs won't break at parse time. The main improvement would be adding a runtime warning when module config is provided without the feature enabled, so users aren't silently getting unexpected behavior.

Recommendation: Approve with minor suggestions above.

@kdy1 kdy1 modified the milestones: Planned, 1.15.11 Jan 28, 2026
@swc-project swc-project locked as resolved and limited conversation to collaborators Feb 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Make it easy to exclude swc_ecma_transforms_module from the final binary

2 participants