Repository navigation
Implement React's jsx/jsxs Factory Changes #34547
Description
Activity
- addedSuggestionAn idea for TypeScriptAn idea for TypeScriptNeeds ProposalThis issue needs a plan that clarifies the finer details of how it could be implemented.This issue needs a plan that clarifies the finer details of how it could be implemented.In DiscussionNot yet reached consensusNot yet reached consensusDomain: JSX/TSXRelates to the JSX parser and emitterRelates to the JSX parser and emitter
on Oct 17, 2019 I currently use
"jsx": "react", "jsxFactory": "h"which can be seen here:https://github.com/opennetwork/vgraph.dev/blob/master/tsconfig.json#L25
hfollows the style of the currentcreateElementfunction, will there be an alternative that can be used in place?Reacted by remag9330, Brian Kim, Jeswin and Brandon BennettReacted by Wesley WighamReacted by Brian Kimhttps://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
Cambios importantes para nosotros:
- JSX
childrensiempre se instala como una matriz en el objeto de utilería, no como argumentos finales. keyse pasará por separado de otros accesorios (en lugar dechildren)
También de nota:
defaultPropsserá obsoleto en los componentes de la función- La difusión
keyserá obsoleta - La cadena
refsquedará en desuso
Es posible que necesitemos nuevas
jsxbanderas, ojsxFactorybanderas, o algo similar. Comprobación necesidad fuerzas para ser cambiado para reflejar esto también dependiendo de si / cómo resolvemoscreateElementlas llamadas.- JSX
It's nearing the end of January 2020, coming up on 1 year from when reactjs/rfcs#107 was opened. It's still open for comments, a finalized set of changes still having not been accepted. I guess we'll keep monitoring it?
Reacted by mike douges, Bnaya Peretz and Noj VekThe first step has just been completed and shipped in Babel 7.9.0:
Blog post: https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154-https-githubcom-babel-babel-pull-11154
PR: babel/babel#11154This new transform eliminates the need for users having to add
Reactin scope of their js files in order for jsx to work, as it is injected by the transform. There's some talk in the PR of why this isn't solved with pragmas:Distinguishing between jsx/jsxs/jsxDEV/createElement is an implementation detail for React and will change in the future. Therefore, we don't think that it makes sense to add a pragma option for all of them. In addition, the signature for jsx/jsxs/etc. is different than createElement, so Preact/Inferno/etc. will not be able to use the new transform the way they currently are.
I'm not familiar with the internals of this PR, I'm just an enthused bystander but I think changes would be something like:
- When the
jsxcompiler option is set topreserveorreact-native, don't throw a warning if you use JSX butReactis not in scope - as the import to the jsx factory function would be added by a further transform step (i.e. Babel) - Add a new value to the jsx compiler option
jsx-automatic(name up for debate, but this is based on the option for the babel transform), that will transform code in a similar manner tobabel-plugin-transform-react-jsxas discussed in Add experimental version of thebabel-plugin-transform-react-jsxtransform babel/babel#11154.
Reacted by mike douges, Jessica Franco and Erik- When the
Will adding the import work here? TS Transformers are unable to successfully add imports during a transformation - unless internally it's done a little differently for jsx transformation (before the binding step)? Which is a shame tbh - would love for transformers to be first class! 😞
Reacted by Mateusz Burzyński, Daniel Rosenwasser and Erik25 remaining items
Change JSX transpilers to use a new element creation method. - Always pass children as props. - Pass key separately from other props. - In DEV, - Pass a flag determining if it was static or not. - Pass __source and __self separately from other props. The goal is to bring element creation down to this logic: function jsx(type, props, key) { return { $$typeof: ReactElementSymbol, type, key, props, }; }How is one supposed to infer the meaning of
Change JSX transpilers to use a new element creation method.andAlways pass children as props.?I read it as asking for changes being make to the jsxFactory function api ?
Am I misreading this ?
Noj Vek (@nojvek) https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154-https-githubcom-babel-babel-pull-11154
Maybe this will add more context to what's going on.Thanks Nicolas Stepien (@nstepien), that deffo provides more context.
IIUC (If I understand correctly) The ask from typescript is to have another compiler flag like
jsxRuntime: automatic | classiclike babel right ? i.e Take existing jsx but emit in a different manner depending on runtime flag?I guess in a way this boils down to the eternal "bake it into core" vs "make it an extension" tradeoff.
There are other interesting projects going on around in the JSX space. e.g https://github.com/ryansolid/solid
Solid works with jsx but emits code like https://svelte.dev/. It does away with virtual dom overhead.
So in terms of Typescript direction, the question that begs answering is if Typescript does specific emits for new React jsxs and new compiler flags, would typescript also do emits for other frameworks that emit jsx in different ways. How much does Typescript give special preference to React over other frameworks?
Is this something that should be done via the transformer plugin api, so it's extensible enough but the core responsibility of Typescript remains at the parser + checker level.
Again, this is just food for thought.
I'm all for evolution of frontend tooling to be simpler, more performant and easier to use.
Reacted by Jesse Stuart and ChristianThanks Nicolas Stepien (@nstepien), that deffo provides more context.
IIUC (If I understand correctly) The ask from typescript is to have another compiler flag like
jsxRuntime: automatic | classiclike babel right ? i.e Take existing jsx but emit in a different manner depending on runtime flag?I guess in a way this boils down to the eternal "bake it into core" vs "make it an extension" tradeoff.
There are other interesting projects going on around in the JSX space. e.g https://github.com/ryansolid/solid
Solid works with jsx but emits code like https://svelte.dev/. It does away with virtual dom overhead.
So in terms of Typescript direction, the question that begs answering is if Typescript does specific emits for new React jsxs and new compiler flags, would typescript also do emits for other frameworks that emit jsx in different ways. How much does Typescript give special preference to React over other frameworks?
Is this something that should be done via the transformer plugin api, so it's extensible enough but the core responsibility of Typescript remains at the parser + checker level.
Again, this is just food for thought.
I'm all for evolution of frontend tooling to be simpler, more performant and easier to use.
I think the wise move is definitely to make it as generic (and therefore, pluggable) as possible, though, I expect most frameworks that rely on JSX will over time migrate to the new
jsxandjsxDevstyle functions, if history is any precedent here.The real issue with leaving it up to being plugins, is that the Compiler API documentation just isn't great. It feels very neglected in comparison (I have this same gripe with babel, for what its worth). Also, with plugins you can only load them via the Node Compiler APIs, you can't have (IIRC) transform plugins added into the tsconfig under
plugins(that appears to only be reserved for the editor plugins).If the story around Plugins gets cleaned up (at least with much better and more detailed documentation, even if the API isn't completely stable), then relying on plugins is the way forward, and you could use React as a reference implementation of said plugins. I think that would be very acceptable.
If the story around Plugins gets cleaned up (at least with much better and more detailed documentation, even if the API isn't completely stable), then relying on plugins is the way forward, and you could use React as a reference implementation of said plugins. I think that would be very acceptable.
perhaps something to think about Daniel Rosenwasser (@DanielRosenwasser) re: making compiler plugins more friendly so Typescript doesn't have to bake everything in it's core.
I'd love to have tsconfig.json support plugins like https://github.com/cevek/ttypescript. There's #14419 which as a ton of 👍 upvotes and wouldn't be too hard to implement.
However some of the Typescript core members have mentioned it won't come anytime soon. I'm not sure exactly why. #14419 (comment)
In any case, don't want to derail the conversation on this topic. I'm not a core Typescript member, it's their call at the end of the day. All I care is that Typescript remains nimble and does a few things really really well like Typechecking and code completion, rather than try to do many things but in a subpar way. It's already a 50MB install.
xiaoxiangmoe commented
on Jul 23, 2020 ContributorMore actionsDaniel Rosenwasser (@DanielRosenwasser) Will this release in TypeScript 4.0.1 ?I found this issue is in Milestone 4.0.1
Reacted by Daniel RosenwasserReacted by Brian KimDanielRosenwasser commented
on Jul 23, 2020 MemberAuthorMore actionsThanks, I've rescheduled to 4.1.
Specifically, we have a draft up (#39199), but the babel transform equivalent is still experimental, and the react changes to allow use of this emit haven't shipped in a stable
reactversion yet; so we may wait untilreact17 actually ships.- addedFix AvailableA PR has been opened for this issueA PR has been opened for this issue
on Sep 9, 2020 So in terms of Typescript direction, the question that begs answering is if Typescript does specific emits for new React jsxs and new compiler flags, would typescript also do emits for other frameworks that emit jsx in different ways. How much does Typescript give special preference to React over other frameworks?
Noj Vek (@nojvek) Yet another JSX-based framework author here. The new changes (jsx and jsxImportSource tsconfig options) have made things simpler actually. The emitted code seems generic and not tied to React. At least for me, it was quite easy to adopt.
Reacted by Noj Vek, Mateusz Burzyński, Ryan Cavanaugh, Kasper Isager Dalsgarð and Alex Tompkins
https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
Major changes for us:
childrenare always installed as an array on the props object - not as trailing arguments.keywill be passed separately from other props (in place ofchildren)Also of note:
defaultPropswill be deprecated on function componentskeywill be deprecatedrefswill be deprecatedWe might need new
jsxflags, orjsxFactoryflags, or something similar. Checking might need to be changed to reflect this as well depending on if/how we resolvecreateElementcalls.