[PoC] Rewrite nested JSX component paths to direct hoisted exports#8293
Open
fhammerschmidt wants to merge 6 commits intorescript-lang:masterfrom
Open
[PoC] Rewrite nested JSX component paths to direct hoisted exports#8293fhammerschmidt wants to merge 6 commits intorescript-lang:masterfrom
fhammerschmidt wants to merge 6 commits intorescript-lang:masterfrom
Conversation
rescript
@rescript/darwin-arm64
@rescript/darwin-x64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/runtime
@rescript/win32-x64
commit: |
tsnobip
requested changes
Mar 13, 2026
Member
There was a problem hiding this comment.
unfortunately I can't test this PR yet because it messes up imports, let's say I use .res.mjs as output suffix, it should generate import like this:
import * as Button$RescriptShadcn from "../registry/base/ui/Button.res.mjs";
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";but instead, it doesn't use .js for runtime but .mjs:
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.mjs";weird that it doesn't get detected by some tests btw!
Member
|
I found another bug around namespace. JsxRuntime.jsx(Sidebar.Sidebar$Provider, ...)but if I enable namespace, it generates this: JsxRuntime.jsx(Sidebar$RescriptShadcn.Sidebar$RescriptShadcn$Provider, ...)while it should be: JsxRuntime.jsx(Sidebar$RescriptShadcn.Sidebar$Provider, ...)the sub component should not be namespaced. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ReScript currently lowers nested JSX component paths like
<Sidebar.Provider>to cross-module member access in generated JS, for exampleSidebar.Provider.make. That works in many cases, but it breaks in environments like Next.js Server Components, where nested component member access can end up as undefined at runtime even though direct top-level component bindings work.This PR changes JSX v4 lowering so nested component modules also emit a hidden direct export for their underlying component function, and transformed JSX runtime calls use that direct export instead of .make member access when available. That keeps existing source syntax and normal exports intact while producing a safer JS shape for server-
component toolchains.
Example before:
Example after:
Justification
The change crosses several compiler layers because the information needed for the rewrite starts in the JSX transform but
is only actionable during JS lowering.
<Sidebar.Provider>is initially just JSX syntax. To compile it to a direct export safely, the compiler needs to:That is why the PR touches:
So the surface behavior change is small, but the data needed to do it correctly spans multiple stages of the compiler pipeline.
Either way I marked it as a PoC since it might not be the best way to do it.