Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flag to emit createRequire matching TS nodenext behavior #728

Merged
merged 1 commit into from Jul 26, 2022

Conversation

alangpierce
Copy link
Owner

@alangpierce alangpierce commented Jul 26, 2022

Progress toward #726

This is currently an opt-in flag handling a nuance in how TS transpiles imports
like these:

import foo = require('foo');

In the new nodenext mode when targeting ESM, TS now transforms this code to use
createRequire. The change is described here:
https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#commonjs-interoperability

This PR adds a flag injectCreateRequireForImportRequire to enable this
different behavior. I'm gating this behind a flag out of caution, though it's
worth noting that TS gives an error when using this syntax and targeting
module esnext, so it will likely be safe to switch to this new emit strategy as
the default behavior in the future.

As I understand it, the main benefit of this change over explicit createRequire
is that it allows a single codebase to be transpiled to Node ESM and Node CJS
while using this syntax. A downside is that createRequire is Node-specific and
needs special support from bundlers, but it looks like webpack can recognize the
pattern. In most situations, real ESM import syntax is probably preferable,
but this syntax makes it possible to force the use of CJS.

The ts-node transpiler plugin system expects transpilers to have this mode as an
option, so this is a step closer to having a compliant ts-node plugin.

Progress toward #726

This is currently an opt-in flag handling a nuance in how TS transpiles imports
like these:
```ts
import foo = require('foo');
```
In the new nodenext mode when targeting ESM, TS now transforms this code to use
`createRequire`. The change is described here:
https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#commonjs-interoperability

This PR adds a flag `injectCreateRequireForImportRequire` to enable this
different behavior. It's unclear if this should eventually become the default,
but it at least seems useful as an option to avoid some ESM/CJS interop
frustration.

As I understand it, the main benefit of this change over explicit `createRequire`
is that it allows a single codebase to be transpiled to Node ESM and Node CJS
while using this syntax. A downside is that `createRequire` is Node-specific and
needs special support from bundlers, but it looks like webpack can recognize the
pattern. In most situations, real ESM `import` syntax is probably preferable,
but this syntax makes it possible to force the use of CJS.

The ts-node transpiler plugin system expects transpilers to have this mode as an
option, so this is a step closer to having a compliant ts-node plugin.
@codecov
Copy link

codecov bot commented Jul 26, 2022

Codecov Report

Merging #728 (90f2307) into main (8a5fdf8) will increase coverage by 0.00%.
The diff coverage is 91.66%.

@@           Coverage Diff           @@
##             main     #728   +/-   ##
=======================================
  Coverage   87.16%   87.17%           
=======================================
  Files          54       54           
  Lines        5711     5722   +11     
  Branches     1346     1349    +3     
=======================================
+ Hits         4978     4988   +10     
  Misses        466      466           
- Partials      267      268    +1     
Impacted Files Coverage Δ
src/Options-gen-types.ts 100.00% <ø> (ø)
src/Options.ts 100.00% <ø> (ø)
src/transformers/RootTransformer.ts 93.65% <ø> (ø)
src/HelperManager.ts 96.87% <80.00%> (-3.13%) ⬇️
src/transformers/ESMImportTransformer.ts 94.11% <100.00%> (+0.24%) ⬆️

📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

@github-actions
Copy link

Benchmark results

Before this PR: 393 thousand lines per second
After this PR: 392.4 thousand lines per second

Measured change: 0.15% slower (0.96% slower to 0.31% faster)
Summary: Likely no significant difference

@alangpierce alangpierce merged commit be09d6b into main Jul 26, 2022
@alangpierce alangpierce deleted the add-createrequire-ts-flag branch July 26, 2022 08:59
1Lighty pushed a commit to Astra-mod/sucrase that referenced this pull request Aug 14, 2022
…erce#728)

Progress toward alangpierce#726

This is currently an opt-in flag handling a nuance in how TS transpiles imports
like these:
```ts
import foo = require('foo');
```
In the new nodenext mode when targeting ESM, TS now transforms this code to use
`createRequire`. The change is described here:
https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#commonjs-interoperability

This PR adds a flag `injectCreateRequireForImportRequire` to enable this
different behavior. I'm gating this behind a flag out of caution, though it's
worth noting that TS gives an error when using this syntax and targeting
module esnext, so it will likely be safe to switch to this new emit strategy as
the default behavior in the future.

As I understand it, the main benefit of this change over explicit `createRequire`
is that it allows a single codebase to be transpiled to Node ESM and Node CJS
while using this syntax. A downside is that `createRequire` is Node-specific and
needs special support from bundlers, but it looks like webpack can recognize the
pattern. In most situations, real ESM `import` syntax is probably preferable,
but this syntax makes it possible to force the use of CJS.

The ts-node transpiler plugin system expects transpilers to have this mode as an
option, so this is a step closer to having a compliant ts-node plugin.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant