Skip to content

Design Meeting Notes, 6/4/2021 #44442

Closed
Closed
@DanielRosenwasser

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.
  • .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.
  • 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.
  • 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
      • Arrow functions with single type parameters (<T>(x: T) => x)
        • Workaround: <T,>(x: T) => x or <T extends unknown>(x: T) => x
      • 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.
    • 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 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.
    • let x = <Foo>yadda; - have to disallow this
    • let f = <T>(x: T) => x; - have to disallow this
    • But can always revisit and relax this!
  • <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.

Metadata

Assignees

No one assigned

    Labels

    Design NotesNotes from our design meetings

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions