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

Update new jsx transform apis, bind to Jsx in compiler, for JSX V4. #49

Merged
merged 37 commits into from
Sep 24, 2022

Conversation

mununki
Copy link
Member

@mununki mununki commented Jun 30, 2022

This PR introduces the new Jsx module in the compiler. This is an initial proposal stage that has objectives and constraints as below.

I don't have a clear picture of Jsx in the future. It could define the primitive types, functions, and modules that are vendors for JSX family, such as React, SolidJs, Remix in future. But I focus to keep the backward compatibility and support for the new jsx mode of React runtime in this stage for now.

src/JsxDOM.res Outdated
@@ -0,0 +1,2078 @@
type element = React.element
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a verbatim copy of another file in the repo?
That could be a problem when someone wants to edit something.

Better to have only once. And in the copy do a one-liner include M instead.

Copy link
Member Author

@mununki mununki Jul 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your comment reminds me of what React and ReactDOM stands for, and the same should go for Jsx and JsxDOM. I remove type element declaration from JsxDOM and relocate some to distinguish what they are.
d3eabbe e93242b

@cristianoc
Copy link
Contributor

This looks good so far. Let's keep it open until the whole V4 ppx is finalised.

@mununki
Copy link
Member Author

mununki commented Jul 1, 2022

Side comment: I verified that V4 & Jsx don't break my test project having dependencies of V3 modules. So, I tried to run the battle-test of V10 & V4 & Jsx on my company projects. I encountered some errors before verifying that V4 & classic, V4 & Jsx will not break the backward compatibility. I'll leave the issue in the compiler.

@mununki mununki mentioned this pull request Jul 1, 2022
13 tasks
@cristianoc
Copy link
Contributor

Side comment: I verified that V4 & Jsx don't break my test project having dependencies of V3 modules. So, I tried to run the battle-test of V10 & V4 & Jsx on my company projects. I encountered some errors before verifying that V4 & classic, V4 & Jsx will not break the backward compatibility. I'll leave the issue in the compiler.

Can you expand a bit on this?
Did you find some problem, and will document that in a new issue?
Or were no problems found?

@mununki
Copy link
Member Author

mununki commented Jul 1, 2022

Side comment: I verified that V4 & Jsx don't break my test project having dependencies of V3 modules. So, I tried to run the battle-test of V10 & V4 & Jsx on my company projects. I encountered some errors before verifying that V4 & classic, V4 & Jsx will not break the backward compatibility. I'll leave the issue in the compiler.

Can you expand a bit on this? Did you find some problem, and will document that in a new issue? Or were no problems found?

I ran V10 & V4 & Jsx on my test project which is a small RescriptReact app. It has dependencies of the RescriptReact module I made with V3 bsconfig. I've tested the scenarios (V3, V4 & classic, V4 & Jsx), and they worked fine.

But I ran V10 compiler in V3 mode on large applications(company projects), it throws several errors. I guess it is not related to V4 or Jsx. So I left the issue in the compiler rescript-lang/rescript#5493

Let me know if anything I can help on that.

@mununki
Copy link
Member Author

mununki commented Jul 2, 2022

I totally agree on the comment from @ryyppy rescript-lang/rescript#5484 (comment) Here is my thought for the future plan. What do you think?

  1. Remove Jsx from rescript-react.
    If the namespace Jsx is occupied here in rescript-react, there will be a problem(in future graceful migrations) when we add Jsx in the compiler. Jsx should be containing the primitive types, functions, modules which are vendors for the 3rd party modules, such as rescript-react, or rescript-solidjs, etc.

  2. Add the new jsx APIs in React.res and ReactDOM.res
    If the upgrade plan is that V4 & the new jsx transform will be shipped with upgrading rescript-react, then we don't need to add a new module here. It is enough to add the new jsx transform React APIs into React.res and ReactDOM.res Those APIs are just for the React anyway.

  3. Add Jsx in the compiler and bind the types to rescript-react
    The initial version of Jsx can be added to the compiler for the experimental feature. Then we can bind the rescript-react to Jsx. For example,

// React.res
type element = Jsx.element

// ReactDOM.res
@module("react/jsx-runtime")
external jsxKeyed: (string, JsxDOM.domProps, string) => Jsx.element = "jsx" // Jsx in the compiler

Does it make sense to you?

@mununki mununki changed the title Add Jsx module Add new jsx transform apis and bind to Jsx in compiler Jul 3, 2022
@mununki mununki changed the title Add new jsx transform apis and bind to Jsx in compiler Update new jsx transform apis, bind to Jsx in compiler Jul 3, 2022
@mununki
Copy link
Member Author

mununki commented Sep 2, 2022

The breaking change is introduced by merging RescriptReact.res into React.res.

Side comment: I realized why some of react component binding was not written with @react.component. Simply it is not possible, because the ppx will transform @react.componet using React.res itself. 🥲 Therefore, I write the binding without @react.component, but it is compatible with ppx V4.

yarn.lock Outdated
@@ -0,0 +1,3501 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, my mistake. I'll drop it.

@cristianoc
Copy link
Contributor

How does one test this?
Perhaps one way is to create a separate sample project, which installs the compiler from master, and the rescript-react from this PR, and tests the various things that have changed?

@mununki
Copy link
Member Author

mununki commented Sep 5, 2022

How does one test this? Perhaps one way is to create a separate sample project, which installs the compiler from master, and the rescript-react from this PR, and tests the various things that have changed?

Yes exactly. That is how I develop and test in my local env.

@cristianoc
Copy link
Contributor

cristianoc commented Sep 5, 2022

How does one test this? Perhaps one way is to create a separate sample project, which installs the compiler from master, and the rescript-react from this PR, and tests the various things that have changed?

Yes exactly. That is how I develop and test in my local env.

Great! Would you create such a project?
That would also be the base example to ask people for feedback.
As it will take a while before both are published in a way that people can try.

@mununki
Copy link
Member Author

mununki commented Sep 5, 2022

How does one test this? Perhaps one way is to create a separate sample project, which installs the compiler from master, and the rescript-react from this PR, and tests the various things that have changed?

Yes exactly. That is how I develop and test in my local env.

Great! Would you create such a project? That would also be the base example to ask people for feedback. As it will take a while before both are published in a way that people can try.

Sure! I'll work on it.

@cristianoc
Copy link
Contributor

Wow! it works! 👍

  • compiler v10.1
  • rescript-react v0.11
  • jsx: {version: 3, v3-dependencies: [rescript-relay]}
  • bs-flags: ["-open ReactV3"]

Still a bit confusing.
It's mainly intended to work when the main project is built with v4.
If the main project is built with v3, it's kind of expected that normal dependencies work out of the box. And they would, if one did not install latest rescript-react.
Thinking...
Perhaps if the main project is build with v3, then there's simply no reason to install latest rescript-react.

@mununki
Copy link
Member Author

mununki commented Sep 21, 2022

At least we don't need to separate the rescript-react version per compiler and jsx version.

(Before)

  • rescript-react>=0.11.0 for compiler v10.1 + JSX v4
  • rescript-react<0.11.0 for compiler v10.1 + JSX v3

(After)

  • rescript-react>=0.11.0 for compiler v10.1 + JSX v4 or JSX v3

@mununki
Copy link
Member Author

mununki commented Sep 21, 2022

It's mainly intended to work when the main project is built with v4.

If the main project is with v4, then dependencies are impossible with v3 by all means.

@mununki
Copy link
Member Author

mununki commented Sep 21, 2022

The option of propagating and v3-dependecies are for the cases, I think
1. dependency is written without @react.component or v3 based. e.g. object props
2. user want to upgrade the compiler v10.1, but have to keep using v3. e.g. async/await
No reason to install the latest rescript-react

@cristianoc
Copy link
Contributor

It's mainly intended to work when the main project is built with v4.

If the main project is with v4, then dependencies are impossible with v3 by all means.

Not beautiful, but it's possible to switch to V3 inside a V4 project, and use a V3 dependency.
I think there are enough escape hatches to cover corner cases, just in case.
Next up, document the upgrade process better. But to do that it would be nice to have some real upgrade experience, so one can direct the docs to issues that do arise in practice.

Perhaps the way to go is to cover the functionality in the upgrade docs, then do another round of feedback.
Based on responses, one could make updates to the mechanism, or to the docs describing it.

@mununki
Copy link
Member Author

mununki commented Sep 21, 2022

Not perfect, but the v3 and v4 apps can use the same latest rescript-react with options you've made. I think this backward compatibility of rescript-react would be a benefit for many users.

@cristianoc
Copy link
Contributor

Anything to clean up here?
Functionality-wise it seems complete now.

@mununki
Copy link
Member Author

mununki commented Sep 23, 2022

It's like done now.
As I added bf2f897, legacy directory could be removed once most users are not using v3 anymore.

@cristianoc
Copy link
Contributor

@mattdamon108 any more feedback, anything to change in this PR before merging?
Next up, publish to npm as @rescript/react@next.

@mununki
Copy link
Member Author

mununki commented Sep 24, 2022

@mattdamon108 any more feedback, anything to change in this PR before merging? Next up, publish to npm as @rescript/react@next.

No, it's done.

Copy link
Contributor

@cristianoc cristianoc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments.
I think we should check in generated js files.
It's not 100% zero generated code anymore for technical reasons, so whatever this produces should be checked in. So we see if it's all needed.

@cristianoc
Copy link
Contributor

@mattdamon108 would you take a look at the checked in .bs.js files? Is everything in them necessary?

@cristianoc cristianoc merged commit 86a27d1 into rescript-lang:master Sep 24, 2022
@cristianoc cristianoc changed the title Update new jsx transform apis, bind to Jsx in compiler Update new jsx transform apis, bind to Jsx in compiler, for JSX V4. Sep 24, 2022
@mununki mununki deleted the jsx branch September 24, 2022 09:23
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

Successfully merging this pull request may close these issues.

2 participants