-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Implement React's jsx
/jsxs
Factory Changes
#34547
Comments
I currently use https://github.com/opennetwork/vgraph.dev/blob/master/tsconfig.json#L25
|
|
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? |
The 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 This new transform eliminates the need for users having to add
I'm not familiar with the internals of this PR, I'm just an enthused bystander but I think changes would be something like:
|
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! 😞 |
Keep also in mind that a new pragma (and similar option) has been added - it’s import { Fragment, jsx, jsxs } from "foo/jsx-runtime"
import { Fragment, jsxDEV } from "foo/jsx-dev-runtime" |
Having though about this a bit, I have a few implementation concerns. We need some feedback from the React core team on this so that we can give a good experience for everyone. NamingIt's not clear what the new flag that users should use is. While this sounds trivial, I really want to get this right. Do we name it VersioningIt sounds like the intent is for That's not possible for us since our transformer is part of our codebase and can't be versioned differently. Any new transform behavior would need a new I think something we need to know from the core team is what the expectation is of incompatible updates to the transformer. Implicit Import BehaviorThe current proposal is for JSX expressions to implicitly import This also means users using the new JSX emit mode in global What we'd probably end up doing is saying that under |
The babel transform necessarily requires either ES or CJS modules to be available (babel import helpers automatically add one or the other depending on It's an emit mode specifically for modules (commonjs or esm); global scripts should still use As an aside, the quick fix I'd recommend for turning a file into a module is to add an |
@Jack-Works In that case, you can write with two different file extensions, like |
The deprecation of |
Personally, I've always just written my components along the lines of import * as React from "react";
import * as ReactDOM from "react-dom";
interface CompProps {
col?: number;
row?: number;
}
const Comp = ({ row = 0, col = 0 }: CompProps) => <p>{row},{col}</p>;
const App = () => <Comp row={1} />;
ReactDOM.render(<App />, document.querySelector("body")); which is notable for two things - never explicitly referencing a type from |
@weswigham thanks for the comment but not sure that addresses the issue I meant to bring up -- namely, if I have a lot of props (say 10-20) but only want to default a few of them, now I have to name every one of them in the destructuring or awkwardly rest them out ala Also for context, the vast majority of my day job is creating/supporting/maintaining a couple of UI libraries, so in order to help with best practices for lots of consumers, I prefer using the @types/react types e.g. |
This is what I do. I don't find this awkward
Concretely, how does React.FC help you do this? What's the best practice here? |
@craigkovatch I don't think using |
@Retsam I second this. In my book and based on my research, I've advised against the use of React.FC. Those types only add noise and hinders readability. |
My ask for Typescript team regarding the RFC is not to treat React is a special snowflake where Typescript only works well with React but not other frameworks. JSX as an interface is adopted by many libraries. The jsxFactory interface i.e I know React authors don't have to consult Typescript before making breaking changes to their apis and you have to follow their decisions but please keep rest of js ecosystem in mind. |
@nojvek have you read the link in the OP? They're not changing the behavior for |
How is one supposed to infer the meaning of I read it as asking for changes being make to the jsxFactory function api ? Am I misreading this ? |
@nojvek https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154-https-githubcom-babel-babel-pull-11154 |
Thanks @nstepien, that deffo provides more context. IIUC (If I understand correctly) The ask from typescript is to have another compiler flag like 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 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 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 @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. |
@DanielRosenwasser Will this release in TypeScript 4.0.1 ?I found this issue is in Milestone 4.0.1 |
Thanks, 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 |
@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. |
https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
Major changes for us:
children
are always installed as an array on the props object - not as trailing arguments.key
will be passed separately from other props (in place ofchildren
)Also of note:
defaultProps
will be deprecated on function componentskey
will be deprecatedrefs
will be deprecatedWe might need new
jsx
flags, orjsxFactory
flags, or something similar. Checking might need to be changed to reflect this as well depending on if/how we resolvecreateElement
calls.The text was updated successfully, but these errors were encountered: