Skip to content

Commit 4c5c354

Browse files
committed
Fix invalid JSX being generated for empty fragments
1 parent e8380f1 commit 4c5c354

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

compiler/core/js_dump.ml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,12 @@ and print_jsx cxt ?(spread_props : J.expression option)
11161116
(* A user defined component or external component *)
11171117
| _ -> expression ~level cxt f tag
11181118
in
1119+
let is_fragment =
1120+
match tag.expression_desc with
1121+
| J.Var (J.Qualified ({id = {name = "JsxRuntime"}}, Some "Fragment")) ->
1122+
true
1123+
| _ -> false
1124+
in
11191125
let children_opt =
11201126
List.find_map
11211127
(fun (n, e) ->
@@ -1129,6 +1135,11 @@ and print_jsx cxt ?(spread_props : J.expression option)
11291135
else Some [e]
11301136
else None)
11311137
fields
1138+
(* For fragments without children we normalize to an empty list so they
1139+
print as <></> instead of </> which is invalid JSX. *)
1140+
|> function
1141+
| None when is_fragment -> Some []
1142+
| other -> other
11321143
in
11331144
let print_props cxt props =
11341145
(* If a key is present, should be printed before the spread props,
@@ -1169,7 +1180,7 @@ and print_jsx cxt ?(spread_props : J.expression option)
11691180
match children_opt with
11701181
| Some _ -> cxt
11711182
| None ->
1172-
(* Put a space the tag name and /> *)
1183+
(* Put a space between the tag name and /> *)
11731184
P.space f;
11741185
cxt)
11751186
else

tests/tests/src/jsx_preserve_test.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ let _props_with_hyphen = <label
192192
data-testid={"test"}
193193
/>;
194194

195+
let _empty_fragment = <></>;
196+
195197
let _fragment = <>
196198
{"Hello, world!"}
197199
</>;
@@ -271,6 +273,7 @@ export {
271273
ComponentWithOptionalProps,
272274
_optional_props,
273275
_props_with_hyphen,
276+
_empty_fragment,
274277
_fragment,
275278
_youtube_iframe,
276279
X,

tests/tests/src/jsx_preserve_test.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ let _optional_props = <ComponentWithOptionalProps i=1 s="test" element={<div />}
124124

125125
let _props_with_hyphen = <label ariaLabel={"close sidebar"} dataTestId="test" />
126126

127+
let _empty_fragment = <> </>
128+
127129
let _fragment = <> {Jsx.string("Hello, world!")} </>
128130

129131
let _youtube_iframe =

0 commit comments

Comments
 (0)