From 51caa4bbd03e2d67866271c13d3a8b1b00db11ce Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Tue, 9 Dec 2025 09:45:02 +0100 Subject: [PATCH 1/4] Fix invalid JSX being generated for empty fragments --- compiler/core/js_dump.ml | 13 ++++++++++++- tests/tests/src/jsx_preserve_test.mjs | 3 +++ tests/tests/src/jsx_preserve_test.res | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/compiler/core/js_dump.ml b/compiler/core/js_dump.ml index ea1c3d5fda..9eedb10d87 100644 --- a/compiler/core/js_dump.ml +++ b/compiler/core/js_dump.ml @@ -1116,6 +1116,12 @@ and print_jsx cxt ?(spread_props : J.expression option) (* A user defined component or external component *) | _ -> expression ~level cxt f tag in + let is_fragment = + match tag.expression_desc with + | J.Var (J.Qualified ({id = {name = "JsxRuntime"}}, Some "Fragment")) -> + true + | _ -> false + in let children_opt = List.find_map (fun (n, e) -> @@ -1129,6 +1135,11 @@ and print_jsx cxt ?(spread_props : J.expression option) else Some [e] else None) fields + (* For fragments without children we normalize to an empty list so they + print as <> instead of which is invalid JSX. *) + |> function + | None when is_fragment -> Some [] + | other -> other in let print_props cxt props = (* 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) match children_opt with | Some _ -> cxt | None -> - (* Put a space the tag name and /> *) + (* Put a space between the tag name and /> *) P.space f; cxt) else diff --git a/tests/tests/src/jsx_preserve_test.mjs b/tests/tests/src/jsx_preserve_test.mjs index 3622e7901d..570ca4607c 100644 --- a/tests/tests/src/jsx_preserve_test.mjs +++ b/tests/tests/src/jsx_preserve_test.mjs @@ -192,6 +192,8 @@ let _props_with_hyphen =