fix(transformer/typescript): rewrite extensions in dynamic import() expressions#20121
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes TypeScript’s rewriteImportExtensions transformer option to also rewrite file extensions inside dynamic import() expressions (when the import source is a literal), matching TypeScript’s behavior more closely and addressing #20120.
Changes:
- Add
enter_import_expressiontraversal hooks through the transformer dispatch chain so dynamicimport()sources can be rewritten. - Extend the TypeScript rewrite-extensions visitor to rewrite
ImportExpressionstring-literal sources. - Add/extend conformance fixtures for both
"rewrite"and"remove"modes covering dynamic imports.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tasks/transform_conformance/tests/babel-preset-typescript/test/fixtures/rewriteImportExtensions/input.ts | New fixture input covering static + dynamic import extension rewriting cases. |
| tasks/transform_conformance/tests/babel-preset-typescript/test/fixtures/rewriteImportExtensions/output.js | New expected output asserting dynamic import() literals are rewritten in "rewrite" mode. |
| tasks/transform_conformance/tests/babel-preset-typescript/test/fixtures/rewriteImportExtensions/options.json | New fixture options enabling rewriteImportExtensions: "rewrite". |
| tasks/transform_conformance/tests/babel-preset-typescript/test/fixtures/removeImportExtensions/input.ts | Extend existing fixture input to include dynamic imports for "remove" mode. |
| tasks/transform_conformance/tests/babel-preset-typescript/test/fixtures/removeImportExtensions/output.js | Extend expected output to assert dynamic import() literals are rewritten in "remove" mode. |
| crates/oxc_transformer/src/typescript/rewrite_extensions.rs | Implement rewriting for ImportExpression when the source is a string literal. |
| crates/oxc_transformer/src/typescript/mod.rs | Forward enter_import_expression to the rewrite-extensions sub-transform when enabled. |
| crates/oxc_transformer/src/lib.rs | Forward enter_import_expression from the top-level transformer into the TypeScript preset. |
Merging this PR will not alter performance
Comparing Footnotes
|
…terals in dynamic import() TypeScript's `isStringLiteralLike` includes `NoSubstitutionTemplateLiteral`, so `import(`./a.ts`)` is also rewritten by tsc. Match that behavior.
I can address the template string concern from copilot above. Noticed that TypeScript also supports this. |
`Atom<'_>` implements `Copy`, so `.clone()` triggers clippy::clone_on_copy.
|
@Dunqing I can revert the import bare template change hand handle that in a followup, if you think that's cleaner. TypeScript and babel supports this in the later versons, but they also now support falling back to a runtime helper for importing substitution template strings via a runtime helper. I could tackle that in a followup too. |
### 🚀 Features - e7163b6 ecmascript: Add known-globals to side-effect-free property reads (#20212) (Dunqing) - 139ab68 ecmascript: Add `property_write_side_effects` to `MayHaveSideEffectsContext` (#20217) (Dunqing) ### 🐛 Bug Fixes - 78c264a parser: Fix conditional expressions with arrow-function alternates in TS (#20356) (camc314) - 5c97b14 minifier: Recognize object spread of object literals as side-effect-free (#20299) (Boshen) - 1ff5c1d transformer/typescript: Rewrite extensions in dynamic `import()` expressions (#20121) (Sverre Johansen) - 1c07b3b diagnostics: Handle `WouldBlock` in stdout writes to prevent panic (#20295) (Boshen) - ade14d4 ecmascript: Enhance side-effect detection for classes, TypedArrays, computed members, and spread (#20213) (Dunqing) ### ⚡ Performance - 5474d0a semantic: V8-style walk-up reference resolution (#20292) (Boshen) ### 📚 Documentation - e4aa5b5 parser/napi, linter/plugins: Add JSDoc comments to raw transfer constants (#20286) (overlookmotel) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Closes #20120
rewriteImportExtensionswas not handling dynamicimport()expressions, only staticimport/exportdeclarations. TypeScript'srewriteRelativeImportExtensionshandles both (viavisitImportOrRequireCallin the ESNext module transformer).The fix adds
enter_import_expressionvisitors at three levels of the transformer dispatch chain. When theimport()source is a string literal, it is rewritten the same way as static imports. Non-literal sources (e.g.,import(variable)) are left unchanged.Test fixtures added for both
"rewrite"and"remove"modes covering dynamic imports.