Skip to content

feat(es/module): support moduleRoot for AMD module IDs - #11964

Open
Kaustubh Singh (Kaus1ubh) wants to merge 3 commits into
swc-project:mainfrom
Kaus1ubh:fix-4014-fresh
Open

feat(es/module): support moduleRoot for AMD module IDs#11964
Kaustubh Singh (Kaus1ubh) wants to merge 3 commits into
swc-project:mainfrom
Kaus1ubh:fix-4014-fresh

Conversation

@Kaus1ubh

@Kaus1ubh Kaustubh Singh (Kaus1ubh) commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Closes #4014

Description

This PR adds support for the moduleRoot configuration property in the AMD module transformer.

When you specify a moduleRoot, SWC will now compute the module ID based on the relative path between that root directory and the file currently being compiled. The goal here is to make SWC perfectly mimic TypeScript's AMD path generation behavior!

I've also made sure we handle edge cases correctly:

  • Config Resolution: If moduleRoot is defined in a .swcrc file, we now correctly resolve it relative to the directory where the .swcrc file lives, rather than just blindly using the process cwd.
  • Programmatic Options: Programmatic options are natively respected without incorrectly rebasing them against the file path.
  • Symlinks: The logic respects jsc.preserveSymlinks = true. I added a component-count heuristic so we safely fall back to filesystem canonicalization only when absolutely necessary (like when dealing with Windows ?\ verbatim paths).
  • Typings: I've updated the WASM typings to make sure the new moduleRoot bindings are exposed consistently across both the core and minifier declarations.

BREAKING CHANGE:

None.

Related issue:

#4014

@changeset-bot

changeset-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: f2213da

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

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

@codspeed-hq

codspeed-hq Bot commented Jun 24, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 2.95%

❌ 1 regressed benchmark
✅ 188 untouched benchmarks
⏩ 61 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation es/lints/libs/three 49.2 ms 50.7 ms -2.95%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing Kaus1ubh:fix-4014-fresh (f2213da) with main (fababa1)

Open in CodSpeed

Footnotes

  1. 61 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d915ee1010

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment thread crates/swc/src/config/mod.rs Outdated
Comment thread crates/swc_ecma_transforms_module/src/amd.rs
@magic-akari

magic-akari commented Jul 9, 2026

Copy link
Copy Markdown
Member

Thanks for working on this.

Before moving forward, I think we should step back and revalidate whether this feature should be added to core at all. A feature request does not necessarily mean that we should implement it, especially when it introduces SWC-specific, non-standard configuration surface area and the underlying issue has been stale for quite a while.

Could you first confirm a few things?

  • Is the original requester’s use case still relevant, or has it already been solved another way?
  • Does Babel have an equivalent feature or configuration option?
  • Does TypeScript actually provide the same behavior we are trying to mirror here, and under what exact conditions?

If there is no current demand or no clear precedent in Babel or TypeScript, I would lean toward not adding this to core for now.

@Kaus1ubh

Copy link
Copy Markdown
Contributor Author

thanks for the feedback magic-akari ,

On the use case, from what I can see in #4014 , the original requester was still interested as recently as 2023 and the issue has been open for 4+ years without anyone proposing a workaround, so it does seem like a real gap people have been running into.

Yes both Babel and TypeScript have something like this, @babel/plugin-transform-modules-amd has a moduleRoot option that works the same way, and TypeScript produces similar behavior through --rootDir when compiling to AMD. So the intent was to mirror existing behavior rather than introduce something new.

I'm still pretty new to the codebase so I might be missing important context around why this was left out originally or what the longer-term direction for AMD support looks like. Happy to hear your thoughts on whether this fits where the project is headed.

@magic-akari

Copy link
Copy Markdown
Member

Thanks for the clarification. When we initially compared the implementation with TypeScript, we overlooked how rootDir affects its output.

After taking another look, TypeScript’s outFile mode—that is, its bundling mode—does indeed derive named AMD module IDs based on rootDir. However, SWC processes files individually, so its behavior is closer to TypeScript’s outDir mode, where this module-name inference does not occur.

I also noticed that TypeScript 7 has removed AMD output support entirely, which is somewhat disappointing.
Given this, I think it would be sufficient to use Babel’s behavior as our reference.

@Kaus1ubh

Copy link
Copy Markdown
Contributor Author

magic-akari the outFile vs outDir difference in TypeScript makes sense. I think I was leaning on that comparison a bit too loosely, and with TypeScript 7 dropping AMD altogether it's probably not the best reference point anyway.

Using Babel as the reference sounds right to me. From what I can tell the current implementation is already pretty close to how @babel/plugin-transform-modules-amd handles moduleRoot, computing the module ID as the relative path from the root to the current file. But I'd be happy to do a more careful side-by-side comparison and tweak anything that doesn't line up. what should we do here?

@Kaus1ubh

Copy link
Copy Markdown
Contributor Author

magic-akari

@magic-akari

Copy link
Copy Markdown
Member

To clarify, the points I raised are no longer blockers for this PR. It can now proceed through the usual review and merge process. Thank you for your patience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Autogenerated Named AMD module names

3 participants