@solidjs/compiler@2.0.0-rc.10
Pre-releasePatch Changes
-
fd36d37:
sourceNames.bindings: compiled binding effects are named by what they write. An attribute effect gets<tag>.<attribute>as written (span.textContent,div.class:active,div.style:color; a template's merged effect lists all of its bindings), a hole's insert is named for the parent it fills (div.children), and a spread passes its tag so the runtime labels its attribute effectdiv.spreadand its children insertdiv.children. The names travel as a trailing options argument oneffect/insert({ name }) and a trailing string onspread;@solidjs/web'seffect,insert, andspreadaccept them and put them on the render effect nodes, where the dev and observe tiers show them in owner paths, attribution chains, and the Propagation track — a binding effect readsspan.textContent ← countinstead ofeffect ← count. Production ignores the names; output with the option off is unchanged. DOM output only;sourceNames: trueturns it on withcomponents. -
fd36d37: Rename the compilers'
componentNamesoption tosourceNames, nowboolean | { components?: boolean }.sourceNames: true(or{ components: true }) is whatcomponentNames: truewas — the tag as written in source ascreateComponent's third argument, on DOM and SSR output. The option is now the home for every kind of source name the compilers can carry into output for the dev and observe runtimes to label the reactive graph with (binding effects and primitives follow); the object form picks kinds.@solidjs/compilerrejectscomponentNamesas an unknown option, so a stale@solidjs/vite-pluginfails loudly rather than compiling without labels. -
fd36d37:
transformSourceNames: the pass behind the Vite plugin'ssourceNames.primitivesoption (a@solidjs/vite-pluginoption, not a compilertransform()option — the compiler exposes it as this standalone function). Reactive primitives (createSignal,createMemo,createOptimistic,createStore,createOptimisticStore,createProjection) resolving to asolid-js/@solidjs/signalsimport are named after the identifier they are declared as — array pattern, binding, property key, or class field — prefixed with the enclosing non-component function (createCounter.value), never overriding an explicitname. Plain JavaScript in and out, so it runs on.ts/.jsmodules too.Stores honour
name:createStore(value, { name: "todos" })labels its property nodestodos.titlein attribution output instead ofstore.title; derived and optimistic stores name their property nodes alongside the projection node. -
235173e: Prune the observability surface:
OBSERVE.attribution.install, theAttributionHookstype,DEV.setConsoleFooter, theTraceSlotandOriginRefaliases,PerformanceTracksOptions.group, and the untestedsolid-js/refreshruntime modes (esm,webpack5,rspack-esm) are gone —@solidjs/compiler'stransformRefresh({ bundler })accepts only"vite" | "standard"to match.ownerPath()is nowOBSERVE.ownerPath(subject)anddiagnosticGuideUrl()isDEV.guideUrl(code);why()also accepts a scope name. Engine record types (RerunEvent,HoldEvent, …) live onsolid-js/attributiononly, andInteractionRef/NavigationRefon the main entries only.@solidjs/diagnosticstypes its record tables off the runtimes' own catalogue (RecordEvent<K>), adds therecoverytable, and bumps the artifactformatVersionto 8. -
a5bd44a: Fix directive transform source maps to point to the original input by running dead-code elimination on the existing AST instead of printing and reparsing between passes.
-
45407d1: JSX passed through a prop other than
children(a layout'sheader, an object of slots, a context value) now hydrates when another id-allocating hole follows it (#3567). Both compilers' hole-scope predicate treated onlyprops.childrenas able to build hydratable content, so a{props.header}hole compiled to a transparent insert: the server reserved the scoped sibling's slot at registration and gave the header's elements the next id, while the client allocated in source order, and every key after the slot shifted. The predicate is now a denylist: a dynamic hole takes a scope unless its value is provably a primitive (literals, template literals, unary, binary and update expressions), so property reads, optional calls, the left operand of||/??, sequence and assignment expressions, and array literals with hydratable entries are all scoped. Ids of elements after such a hole shift by one slot on both sides. -
6717d35:
sourceNamesfollowsdevin both JSX compilers. Unset, every kind (components,bindings) is on whendev: trueand off otherwise;true/falsesets every kind (sourceNames: falseopts a dev build out); the object form picks, and each kind it leaves unspecified followsdev(previouslyfalse). Production output (dev: false) is byte-identical with the option set or unset.@solidjs/babel-plugin'sPluginConfig.sourceNamesis now optional. Dev builds label components (createComponent(Home, props, "Home")) and binding effects (span.children) out of the box, so diagnostics and the Performance panel read as source without build-tool configuration.Primitive naming (
createSignal(0, { name: "count" })) stays with@solidjs/compiler's standalonetransformSourceNamespass, which the build tool runs on every module independently of the JSX compiler; it is not a JSX-transform kind, and the READMEs and RFC now say so. -
1735074: SSR: a component's props literal with getters compiles to a module-level constructor with shared getters (
hoistProps, default on) instead of an object literal, which V8 builds in dictionary mode with a closure per getter per instance. Same own keys, order, descriptors and prototype; a props getter is now defined only for a read through its own object — copying its descriptor elsewhere throws (dev names the rule). Sites closing over a reassigned or later-declared binding,this, orargumentskeep the literal. Babel and the native compiler emit the same output. -
e10a4ba: SSR: attributes written after an element's last spread are markup, not a source.
<li {...rest} class="row" data-id={id}>compiles tossrElement("li", rest, …, _sk$, () => ' class="row"' + ssrElementAttribute("data-id", id))— statics written as the template path writes them, dynamics throughssrElementAttribute(the spread walk's rules for one key), the whole string a literal when every part is static — with a hoisted skip predicate (var _sk$ = k => k === "class" || k === "data-id", one per key set) so the spread's own copies of those keys are never read or emitted. No later source can override a trailing attribute, so the output is unchanged; the thunk runs where the trailing source's getters used to be read, so hydration ids keep their order. What goes away per element is the trailing object literal (with getters, a dictionary-mode object and a closure per getter), its key list, and the precedence check on every key of the spread — an element whose only other source is the spread now serializes from one plain object. Attributes before a spread stay a source, and a source literal with getters (<li data-id={id} class="row" {...rest}>) now compiles to the same hoisted constructor as a component's props (hoistProps). Spread-static-tail server bench, 500 rows: statics after the spread 1.31×; a dynamic and a static after the spread 1.42× (1.22× from the hoisted source form, 1.17× from the thunk on top); the same attributes before the spread 1.21×. Child properties (innerHTML,textContent,children), a textarea'svalue, reserved namespaces and JSX-valued attributes stay sources. -
9adf007: Escape static text on SSR spread elements (#3557)
- Static text children of a spread element (
<div {...props}>a <b></div>) are now HTML-escaped at compile time in both compilers, matching the template path;scriptandstylechildren stay raw. - A static textarea
valuefolded into the template (<textarea value="a <b>" />) is escaped in both compilers. - The Babel plugin no longer folds a textarea
valueinto children on an element that carries a spread, so the value stays a prop and precedence follows JSX source order, matching the native compiler. - Static string props on the Babel spread paths are rebuilt from their decoded value, so
<div {...props} title="a & b" />no longer double-encodes entities.
- Static text children of a spread element (