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

JSX spread children #2245

Closed
thejimmylin opened this issue May 11, 2022 · 2 comments
Closed

JSX spread children #2245

thejimmylin opened this issue May 11, 2022 · 2 comments

Comments

@thejimmylin
Copy link

Basically I want to write something like this:

The problems

const App = () => {
    return <div>{...["Hello", " ", "spread", " ", "children"]}</div>
}

And I wish esbuild could turn it to something like:

const App = () => {
    return h("div", null, ...["Hello", " ", "spread", " ", "children"]);
};

But that is not the case, esbuild will turn it to something else. I will show it below.

And also, I find it possible when I use TS to translate JSX like this example in TS playground.

More information

Here are some output for esbuild/tsc and tsx/jsx.

Input

The intput is always these code, but with .tsx and .jsx extension.

import * as React from "react";
function Greet() {
  return <h1>{["Hello", " ", "world!"]}</h1>;
}
function SpreadGreet() {
  return <h1>{...["Hello", " ", "world!"]}</h1>;
}

Output1 - .tsx + esbuild

esbuild index.tsx --outfile=esbuild-tsx-output/index.js

import * as React from "react";
function Greet() {
  return /* @__PURE__ */ React.createElement("h1", null, ["Hello", " ", "world!"]);
}
function SpreadGreet() {
  return /* @__PURE__ */ React.createElement("h1", null, ["Hello", " ", "world!"]);
}

Output2 - .tsx + tsc

tsc index.tsx --target es6 --moduleResolution node --jsx react --outdir tsc-tsx-output/

import * as React from "react";
function Greet() {
    return React.createElement("h1", null, ["Hello", " ", "world!"]);
}
function SpreadGreet() {
    return React.createElement("h1", null, ...["Hello", " ", "world!"]);
}

Output3 - .jsx + esbuild

esbuild index.jsx --outfile=esbuild-jsx-output/index.js

✘ [ERROR] Unexpected "..."

    index.jsx:6:14:
      6 │   return <h1>{...["Hello", " ", "world!"]}</h1>;~~~

1 error

Output4 - .jsx + tsc

tsc index.jsx --allowjs --target es6 --moduleResolution node --jsx react --outdir tsc-jsx-output/

import * as React from "react";
function Greet() {
    return React.createElement("h1", null, ["Hello", " ", "world!"]);
}
function SpreadGreet() {
    return React.createElement("h1", null, ...["Hello", " ", "world!"]);
}

You may reproduce the results above about with this repo.

Why this is a problem

As this issue has mentioned, JSX spread children is a nice feature and is technically possible.

React itself don't want/need this because it want its users to use the key prop to structure an array of JSX node and React will flatten these nested array later, when it structure the JSX tree/VDOM things.

However, that is actually more like an implementation detail, which should not be noticed by those who use JSX without React. It will be great if esbuild allows these syntax.

@evanw
Copy link
Owner

evanw commented May 11, 2022

Makes sense. Looks like TypeScript's behavior regarding this changed in TypeScript 4.5+, and esbuild should be updated to match this new behavior from the TypeScript compiler.

@evanw evanw closed this as completed in 7e2d75c May 11, 2022
@thejimmylin
Copy link
Author

thejimmylin commented May 11, 2022

Thanks a lot! :))

Edit:
A just noticed that the new esbuild@0.14.39 is updated to match this behavior. That is fast! Thank you!!

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

No branches or pull requests

2 participants