Thank you for filing! Check list:
Summary
When using the generic JSX transform with "preserve": true, external component bindings generate invalid JSX syntax like <prim => Module.Component(prim)> instead of valid JSX.
ReScript Version
12.0.0
Minimal Reproduction
https://github.com/han-tyumi/rescript-jsx-preserve-bug
git clone https://github.com/han-tyumi/rescript-jsx-preserve-bug.git
cd rescript-jsx-preserve-bug
npm install
npx rescript build
cat Test.jsx
Files
rescript.json:
{
"name": "preserve-bug",
"sources": ["."],
"package-specs": {
"module": "esmodule",
"in-source": true
},
"suffix": ".jsx",
"jsx": {
"module": "Preact",
"preserve": true
}
}
Preact.res (minimal bindings):
type element
type component<'props> = 'props => element
@module("preact/jsx-runtime")
external jsx: (component<'props>, 'props) => element = "jsx"
@module("preact/jsx-runtime")
external jsxs: (component<'props>, 'props) => element = "jsxs"
type fragmentProps = {children?: element}
@module("preact/jsx-runtime")
external jsxFragment: component<fragmentProps> = "Fragment"
type domProps = {children?: element}
module Elements = {
external someElement: element => option<element> = "%identity"
@module("preact/jsx-runtime")
external jsx: (string, domProps) => element = "jsx"
@module("preact/jsx-runtime")
external jsxs: (string, domProps) => element = "jsxs"
}
Test.res:
// Component module pattern with external make
module Head = {
type props = {children?: Preact.element}
@module("some-lib")
external make: props => Preact.element = "Head"
}
// Using the component
let test = <Head> <div /> </Head>
Expected Output
Valid JSX that can be processed by standard JSX transformers:
let test = <SomeLib.Head>
<div />
</SomeLib.Head>;
Actual Output
Invalid JSX with arrow function syntax:
let test = <prim => SomeLib.Head(prim)>
{Primitive_option.some(<div />)}
</prim => SomeLib.Head(prim)>;
Notes
- Lowercase DOM elements work correctly in preserve mode (e.g.,
<div> stays as <div>)
- Internal component modules (with ReScript-defined
make functions) work correctly (e.g., <MyComponent.make>)
- External component bindings produce the invalid arrow function syntax shown above
This prevents using preserve mode with frameworks like Preact/Fresh where you need to bind to external components.
Thank you for filing! Check list:
Summary
When using the generic JSX transform with
"preserve": true, external component bindings generate invalid JSX syntax like<prim => Module.Component(prim)>instead of valid JSX.ReScript Version
12.0.0
Minimal Reproduction
https://github.com/han-tyumi/rescript-jsx-preserve-bug
git clone https://github.com/han-tyumi/rescript-jsx-preserve-bug.git cd rescript-jsx-preserve-bug npm install npx rescript build cat Test.jsxFiles
rescript.json:
{ "name": "preserve-bug", "sources": ["."], "package-specs": { "module": "esmodule", "in-source": true }, "suffix": ".jsx", "jsx": { "module": "Preact", "preserve": true } }Preact.res (minimal bindings):
Test.res:
Expected Output
Valid JSX that can be processed by standard JSX transformers:
Actual Output
Invalid JSX with arrow function syntax:
Notes
<div>stays as<div>)makefunctions) work correctly (e.g.,<MyComponent.make>)This prevents using preserve mode with frameworks like Preact/Fresh where you need to bind to external components.