microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.33k stars 12.54k forks source link

rewriteRelativeImportExtensions does not rewrite the extension for an import expressions unless the file is detected to be a module #60599

Open bradzacher opened 1 week ago

bradzacher commented 1 week ago

🔎 Search Terms

rewriteRelativeImportExtensions, import expression

🕗 Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?rewriteRelativeImportExtensions=true#code/PTAEEsFsAcHsCcAuoDkA6YAzWs2IM4oDcAsAFBRxIAU6WOehAlOUA

💻 Code

Test One

import('./foo.ts')

Test Two

import './foo.ts';
import('./foo.ts')

🙁 Actual behavior

JS Output

Test One

import('./foo.ts') // ❌

Test Two

import './foo.js'; // ✅
import('./foo.js') // ✅

🙂 Expected behavior

JS Output

Test One

import('./foo.js') // ✅

Test Two

import './foo.js'; // ✅
import('./foo.js') // ✅

Additional information about the issue

No response

jakebailey commented 1 week ago

I don't think this has to do with the import being twice, but rather module detection? This one rewrites paths too: https://www.typescriptlang.org/play/?rewriteRelativeImportExtensions=true#code/JYWwDg9gTgLgBAcgHQHoBmEICYkwM4IDcAsAFCiSwAUy6muBAlGUA

bradzacher commented 1 week ago

Looks like you might be right.

export {};
import('./foo.js')

playground

This also correctly transforms the extension.

jakebailey commented 1 week ago

@andrewbranch

jakebailey commented 1 week ago

FWIW I'm not sure that this is incorrect behavior; this transformation was only intended on applying in modules, so if we don't think a file is a module, then it won't happen.

What condition are you running under where the file is not a module?

(Maybe we should rewrite imports in import nodes in scripts, given they can appear there?)

bradzacher commented 1 week ago

If you're working in LTS node then the only way to access ESM in CJS is via import expressions. But it's not a real usecase I had in mind -- I was just testing the feature and this surprised me because there was no mention of it being restricted on the announcement, and there aren't docs yet (https://www.typescriptlang.org/tsconfig/#rewriteRelativeImportExtensions :sad:).

jakebailey commented 1 week ago

To be clear a "module" to us means "not a global script"; CJS are modules in this scheme.