ds300 / react-native-typescript-transformer

Seamlessly use TypeScript with React Native
MIT License
657 stars 50 forks source link

Why JSX is not set to react-native? #46

Closed henrikra closed 6 years ago

henrikra commented 6 years ago

I noticed from JSX docs that JSX has also option react-native for it.

Here are all three different modes for JSX

TypeScript ships with three JSX modes: preserve, react, and react-native. These modes only affect the emit stage - type checking is unaffected. The preserve mode will keep the JSX as part of the output to be further consumed by another transform step (e.g. Babel). Additionally the output will have a .jsx file extension. The react mode will emit React.createElement, does not need to go through a JSX transformation before use, and the output will have a .js file extension. The react-native mode is the equivalent of preserve in that it keeps all JSX, but the output will instead have a .js file extension.

So why react-native-typescript-transformer is telling us to configure JSX to react instead of react-native. Are there some drawbacks etc? :D

ds300 commented 6 years ago

Hi Henrik,

Good question! I agree, the situation is a little confusing, and the reason for it is historical rather than technical. the reason for it is both historical and technical.

When React first appeared on the scene, most JS tooling was not compatible with the JSX syntax. To mitigate this, people would only put JSX syntax in files with the extension .jsx. Eventually the tooling caught up and now most of us put JSX in .js files as though it were part of the ECMAScript standard.

When TypeScript first added support for JSX, people were still using the .jsx extension a lot, so the TS crew made .tsx files compile to .jsx files. This is how the --jsx react option works.

The React Native ecosystem fully embraced the .js extension to the point that the bundler metro doesn't even support loading .jsx files. This posed a problem for people using TypeScript with React Native because TypeScript only supported .jsx files. I can't actually remember how people would use TypeScript with React Native back in those days, but it was probably ugly.

The --jsx react-native option was added to let developers compile .tsx files to ordinary .js files.

edit: In addition, it leaves the JSX untouched, like the preserve option, because React Native used to provide error reports which rendered the JSX (maybe still does? I haven't seen them in forever).

At the time of writing, react-native-typescript-transformer uses Babel as a secondary compilation step, so it shouldn't matter whether you use react, preserve, or react-native :)

henrikra commented 6 years ago

Great explanation! So would it makes sense to change readme to use react-native if it doesn't matter and it semantically more relevant? :D

ds300 commented 6 years ago

Sure, makes sense. I'll do that.

ds300 commented 6 years ago

Hmm actually I misremembered what the react-native option does, which is highly embarrassing since I wrote it 🤦‍♀️

It actually leaves the JSX untouched, which makes it identical to the preserve option except that it emits .js files instead of .jsx files. This is already mentioned in the README so I'll leave it untouched.

henrikra commented 6 years ago

You are right! I didn't notice it. Thanks for your help :)

zen0wu commented 6 years ago

Actually using react-native would not work, because react-native would leave the JSX tags and then babel would change that to React.createElement. The problem is, TypeScript compiler would rename the imported React to things like react_1 or something, which would cause React.createElement fails to find the variable React. It would be great if the plugin can somehow solve this automatically, but react works great.

youngjuning commented 5 years ago

0.57.3 is not support

fantasy525 commented 5 years ago

hich would ca

thank you ,I set jsx 'react-native',but i got a error:can't find the variable React; so I set jsx 'react',it works!