facebook / jsx

The JSX specification is a XML-like syntax extension to ECMAScript.
http://facebook.github.io/jsx/
1.96k stars 132 forks source link

RFC: An evolved JSX 2.0 proposal #124

Open nojvek opened 4 years ago

nojvek commented 4 years ago

I acknowledge that the old JSX 2.0 proposal (#65) had way too many comments to keep up a discussion and is closed for discussion.

This proposal tries to accomodate many existing issues. It is based on the existing JSX 2.0 proposal by @sebmarkbage.

Guiding principles

  1. Simpler and closer to existing JavaScript syntax. JSX is an extension of Javascript.
  2. Incorporate less of the html quirks.

What this proposal isn't

  1. No special behavior for control structures like if, else e.g special behavior for <If> tags. JSX semantics should only focus on expressing the tree structure of tags and expressions. The logic structure should be dictated by existing JS syntax e.g ternary x ? y : z and someArray.map to iterate over arrays. When do expressions make it to ES spec, they can focus on more expressive logic semantics.

  2. Concerned with how jsx gets transpiled and emitted. This proposal purely focuses on syntax. i.e no special syntax for event handler binding.

Issues taken into consideration

The proposal purely focuses on parser level semantics

4 - Drop HTML encoding in text and attributes.

21 - Computed attribute names.

23 - Object short hand notation.

25, #51, #64 - Drop the need for curlies around attribute values if they're a single literal, or parenthesis.

35, #8 - Crazy Idea: Deprecate JSXText?

68 - Make JSX even more like JS

7 - Comments in JSXElement

117 - non-breaking changes for attribute values

108 - Computed attribute names

103 - Curly braces for attribute expressions are pointless and ugly

76 - Destructuring

53 - Remove JSXElement from JSXAttributeValue production

The major breaking changes to existing spec

  1. Parens to specify expressions like JS instead of curly braces e.g {...} -> (...)
  2. JSXChildren are either JSXElements, ParensExpression or Literals.
  3. There is no JSXText. No special entity encoding or implicit whitespace to deal with.

JSX Elements

JSXElement remains as is. No changes here.

JSXAttribute

JSXAttributeValue

ParensExpression: (expr) replaces {expr} as expression syntax since JS already understands (...). For x={{hello:world}}, { has double meaning. The first use is to signify expression, and the next use is the object initializer.

x=((((((1)))))) still means an expression, no matter how many parentheses.

JSXChild

Complex Example:

<div>
  (users.map(user => 
    <>
      <User user/>
      " "
      (user.isPro() ? "Pro" : "Free")
    </>
  ))
  <span style=({fontWeight: 400})>`There are`</span>
  `${users.length} `
  (users.length == 1 ? "User" : "Users")

  <script>
    // We can have single line comments
    /* or 
     * multiline comments like JS
     */
    `
    multiline text body can contain all sorts of weird characters <>&"'¢£¥€©®

    including new lines with ${user.name} expressions
    `
  </script>
</div>
nojvek commented 4 years ago

@sebmarkbage / @ryancavanaugh just wondering if you have any opinions ^

I wonder who else needs to be pinged to have a serious discussion of pros/cons and viability.

A part of me wants to create a typescript prototype with “jsxVersion: 2” compiler flag.