Repository navigation
Conversation
|
Fix from review (fb3768b): every The IIFE stays inside Merged #14's fixes in. |
… ES module output, not as named function expressions
…ir env 📝 elsewhere named fn expressions, without the IIFE
|
Restacked on
The review-fix merges are folded into the branches' own commits. The code is unchanged apart from #21's changes. Only On every branch, |
|
Closing: this change only mattered for React Compiler. Since the review fix ( |
Stacked on #14 (
esm-const).In ES module output,
for's iterator fns are bound withletfn*to an anonymous fn and call themselves through that local, instead of being named function expressions that call themselves by name. React Compiler rejects the named self-calls ("Expected value kind to be initialized"), so any component usingforwas skipped.cljs.core/for(macro): in ES module output it emits(letfn* [iter (fn [s] ...)] iter)instead of(fn iter [s] ...). Classic output is unchanged.letfn*: a fn named after its binding (letfn's) still refers to itself by its own name. An anonymous fn now refers to itself through the binding. Before, the self-call resolved to a namespace var that doesn't exist.React Compiler
On a test component using
for,case,loopanduseState(babel-plugin-react-compiler1.0), the component compiles with 8 memo slots, where before it was rejected. The compiled output, with components marked"use memo", renders the same HTML through React's server renderer as without React Compiler.I also tried hoisting the
letfninto the function's hoistedlets instead of an IIFE. React Compiler accepted the component but memoized nothing (0 slots), so the IIFE stays.Next blocker, in a separate PR: sequential destructuring (
(let [[a b] (useState ..)] ..)) compiles to thev?.nth ? v.nth(..) : nth(..)fast path, which React Compiler treats as an unknown call; it memoizes much less (0 instead of 10 slots in a two-useStatecomponent).Performance
formicro-benchmarks againstesm-const(release build, rolldown-minified, Node 26, 3 alternating runs):esm-constforover 1,000 itemsforwith nested:whenforrepeated many timesforinside aloopThe cost is per
forexpression (the IIFE binding theletfn), not per item.Tests
script/test-esm: 0 failures, 0 errors. It includes a new build test offorwith:let,:whenand:while, nested bindings,forin aloopand an infinite sequence, and that there are no named iterator function expressions.