Closed
Description
ES Modules in Node
https://gist.github.com/weswigham/22a064ffa961d5921077132ae2f8da78
- Last time we left off talking about
.tsx
syntax and how it affected JS module support..cjs
and.mjs
need a corresponding input format for them..cts
and.mts
.jsx
->.tsx
.mjsx
->.mtsx
?- Can potentially get away with just putting JSX in
.mts
. - Is
.mjsx
a thing? - No, probably an assumption that
.mjs
can contain JSX. - JSX is a superset of JS, right?
- Yes but not a superset of TS.
- In
.js
files we always parse JSX anyway.- We were trying to be "descriptive", not "prescriptive" - not something we're in love with.
- Can potentially get away with just putting JSX in
.cjs
and.mjs
- Have to start recognizing these as inputs under
allowJs
- Idea: in the new Node mode, we "do the right thing" - otherwise, we just assume they should be handled as regular
.js
files. - No
.cjsx
,.mjsx
. - Do we conditionally parse JSX on whether the JSX flag is specified?
- No, wouldn't start now either.
- We just complain in grammar checks if you use JSX syntax without the flag.
- Have to start recognizing these as inputs under
- What is the distinction between
.js
and.jsx
in today's implementation?- None.
.cts
and.mts
extensions- These include TypeScript syntax and correspond exactly to
.cjs
and.mjs
respectively. - That way we don't have to add a flag to say "emit as
.cjs
" and "emit as.mjs
" from.ts
input.
- These include TypeScript syntax and correspond exactly to
- How do we avoid
.ctsx
and.mtsx
?- Can just assume
.cts
includes JSX,.mts
includes JSX. - Would have to get rid of
- Angle bracket type assertion syntax (
<Type>expression
)- Workaround:
expression as Type
- Workaround:
- Arrow functions with single type parameters (
<T>(x: T) => x
)- Workaround:
<T,>(x: T) => x
or<T extends unknown>(x: T) => x
- Workaround:
- Infinite lookahead?
- Already do infinite look-ahead in other places.
- Could try parsing an arrow function following specific JSX opening tags.
- Then error if you can successfully parse.
- Feels like we can do the disambiguation.
- But the
>
in the arrow is not illegal.- "Could've sworn that JSX rejected certain characters."
- "Both major compilers just allowed them." 😕
- What if you unsuccessfully parse?
- You can reject the perfectly-written arrow functions, but imperfectly-written ones will get bad error messages.
- Angle bracket type assertion syntax (
- Feels weird that you might try to rename your file and then get errors with no explanation.
- Makes migration harder.
- Would you use
.cjs
for React? It sounds like a Node-ism.- Electron?
- Maybe worth checking with stewards of JSX (e.g. reach out to React team).
- Can just assume
- Can always support
.cts
and.mts
without JSX support and add it later.- But that means you have to reject the ambiguous syntax as well.
- Otherwise you end up with the same issue of
.ts
syntax conflicting with JSX syntax.
- Otherwise you end up with the same issue of
let x = <Foo>yadda;
- have to disallow thislet f = <T>(x: T) => x;
- have to disallow this- But can always revisit and relax this!
- But that means you have to reject the ambiguous syntax as well.
<T>3</T>
- JSX Open, 3, LessThan, RegExp, Oops End-of-File
- Could consider a prologue directive like
// @jsx: true
- Are we overthinking this based on arrow functions?
- Prologue directives affecting parsing is not something our parser is wired up for.
- We do these things post-parse.
- TmLanguage grammars too!
- Can't say "switch to TypeScript-React" right after.
- Start-line headers? Something we can talk about with partner teams.
- Issue an error on and generic arrow functions?
- Has the same downsides of the JSX variant from the start?
- But future-proofed.
- Gives us more direction, but doesn't fix the issue of
.tsx
->.mts
being weird...but works better for.ts
->.mts
. - Editor support and command line tooling for helping the migration?
- Sounds cool!
- Conclusion:
.mts
and.cts
parsed as.ts
, additional grammar error to inform people of what you meant if you wrote specific constructs. - Declaration for
.cjs
,.mjs
.d.cts
,.d.mts
- We used to be scared of this because of the new resolution rules, but now we read directory contents ahead of time to see whether a file read will succeed.
- We would have to have separate shapes for different modules depending on how it's imported.
- You only need to look for
.d.mts
if you import with an.mjs
extension, right?- Yes.
- Something worth thinking as a follow-up:
- JSON:
.d.tson
? - Extension priorities will add a lot of complexity and work.
- JSON: