-
Notifications
You must be signed in to change notification settings - Fork 471
JSX preserve mode: fix "make is not a valid component name" #7831
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
Conversation
rescript
@rescript/darwin-arm64
@rescript/darwin-x64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/runtime
@rescript/win32-x64
commit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your continued efforts to resolve this.
Could you add a new test case using the example from #7432?
I also think this code no longer makes sense because of that change:
rescript/compiler/syntax/src/jsx_v4.ml
Lines 96 to 108 in a09a3d7
(* Build a string representation of a module name with segments separated by $ *) | |
let make_module_name file_name nested_modules fn_name = | |
let full_module_name = | |
match (file_name, nested_modules, fn_name) with | |
(* TODO: is this even reachable? It seems like the fileName always exists *) | |
| "", nested_modules, "make" -> nested_modules | |
| "", nested_modules, fn_name -> List.rev (fn_name :: nested_modules) | |
| file_name, nested_modules, "make" -> file_name :: List.rev nested_modules | |
| file_name, nested_modules, fn_name -> | |
file_name :: List.rev (fn_name :: nested_modules) | |
in | |
let full_module_name = String.concat "$" full_module_name in | |
full_module_name |
Transforming make
to FileName$ModuleName
appears irrelevant now since that won't be called anymore.
Given this, should this behavior become the default regardless of preserve JSX? If so, the work in #7203 could be undone.
The uppercase function name is relevant for the React devtools. Otherwise all your components will have the name "make" there. Also, React Compiler does not recognize lowercase component functions. |
I assumed wrongly that the React compiler would follow function make(props) {
return null;
}
let C = {
make: make
};
let c = <C.make />; The |
0d4cc14
to
941b636
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave this to @cristianoc. I can't quite tell whether it's harmless, so I suggested a few changes to tighten it up. Think of them as ideal-world tips since I'm not sure they're all feasible.
@@ -245,6 +245,10 @@ let subst_map (substitution : J.expression Hash_ident.t) = | |||
turn a runtime crash into compile time crash : ) | |||
*) | |||
match Ext_list.nth_opt ls (Int32.to_int i) with | |||
(* 7432: prevent optimization in JSX preserve mode *) | |||
| Some {expression_desc = J.Var (Id {name = "make"})} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check could in theory affect each make
function right?
Could we add some sort of check if that make
returns a Jsx.element
type? Just to further limit the scope when this kicks in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no type this down the compiler stack
(* 7432: prevent optimization in JSX preserve mode *) | ||
| Lprim | ||
{ | ||
primitive = Pjs_call {prim_name = "jsx" | "jsxs"} as primitive; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same remark, very unlikely that jsx
is not going to come from ReactRuntime call, if we can further tighten it that be great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's plenty guarded against risk already
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not the same check that preserve mode is on?
I guess it's kind of implicit, and only a super corner case would have the same name, but since it's so easy to add why not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check for preserve mode is already there (below).
@@ -224,6 +223,47 @@ let _youtube_iframe = <iframe | |||
referrerPolicy={"strict-origin-when-cross-origin"} | |||
/>; | |||
|
|||
function make(_props) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding the tests!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks plenty safe -- good to go for me
nice fix!
(* 7432: prevent optimization in JSX preserve mode *) | ||
| Lprim | ||
{ | ||
primitive = Pjs_call {prim_name = "jsx" | "jsxs"} as primitive; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's plenty guarded against risk already
(* 7432: prevent optimization in JSX preserve mode *) | ||
| Lprim | ||
{ | ||
primitive = Pjs_call {prim_name = "jsx" | "jsxs"} as primitive; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not the same check that preserve mode is on?
I guess it's kind of implicit, and only a super corner case would have the same name, but since it's so easy to add why not
I tested against a large project, and the changes looked fine to me. BTW, if I remove the checks for the JSX preserve mode and do |
Closes #7432 by disabling two optimization when in JSX preserve mode.
Ideally, the optimization should only be disabled for actual JSX expressions, but I have not found how to do that yet.