github.com-facebook-react
all · 24 devs · built 2026-08-09
Repository snapshot
Monthly reports
No monthly reports available yet.
Performance over time
ETV stacked by Growth, Maintenance and Fixes — 90-day moving average, normalized to ETV / month.
Average performance per developer
ETV per active developer per month — 30-day moving average.
Active developers over time
Unique developers committing each day — 90-day moving average.
Knowledge concentration
How dependent is this repo on a small number of contributors? Higher top-1 share = higher key-person risk.
Sebastian Markbåge owns 29.3 % of commits.
Top contributors
Most impactful commits
Top 20 by ETV in the all-time window.
- 4.5ETVImplement Partial Hydration for Activity (#32863) Stacked on #32862 and #32842. This means that Activity boundaries now act as boundaries which can have their effects mounted independently. Just like Suspense boundaries, we hydrate the outer content first and then start hydrating the content in an Offscreen lane. Flowing props or interacting with the content increases the priority just like Suspense boundaries. This skips emitting even the comments for `<Activity mode="hidden">` so we don't hydrate those. Instead those are deferred to a later client render. The implementation are just forked copies of the SuspenseComponent branches and then carefully going through each line and tweaking it. The main interesting bit is that, unlike Suspense, Activity boundaries don't have fallbacks so all those branches where you might commit a suspended tree disappears. Instead, if something suspends while hydration, we can just leave the dehydrated content in place. However, if something does suspend during client rendering then it should bubble up to the parent. Therefore, we have to be careful to only pushSuspenseHandler when hydrating. That's really the main difference. This just uses the existing basic Activity tests but I've started work on port all of the applicable Suspense tests in SelectiveHydration-test and PartialHydration-test to Activity versions.Sebastian Markbåge · 3ef31d19 · 2025-04-23
- 2.8ETV[eslint-plugin-react-hooks] updates for component syntax (#33089) Adds support for Flow's component and hook syntax. [docs](https://flow.org/en/docs/react/component-syntax/)Jan Kassens · 4c4a57c4 · 2025-05-02
- 2.6ETV[react-devtools-facade] 2/ implement component tree tools (#36597) Adds the component-tree building blocks and the `createTools(facade)` assembler — the first tools layered on top of the `installFacade` hook from commit 1. ### `createTools(facade): Tools` Reads the facade's tracked state (fiber roots + per-renderer internals) and returns a plain `Tools` object — no globals; the integrator decides what to do with it. Tools return **typed, plain JavaScript values** (or `{error}`); serialization (to an integration package's wire format) is left to the caller. ### Tools - **`getComponentTree(depth?, rootUid?)`** — the component tree as a flat array of `{uid, type, name, key, firstChild, nextSibling}` nodes (an adjacency list referencing other nodes by label). - **`getComponentByUid(uid)`** — one component's `{type, name, key?, props?, hooks?}`. For function components, `hooks` is the inspected hooks tree (nested `subHooks`), obtained via `react-debug-tools'` `inspectHooksOfFiberWithoutDefaultDispatcher` with the renderer's injected dispatcher (normalized by `getDispatcherRef`) — so hooks introspection never falls back to, or bundles, React's shared internals. - **`findComponents(name, rootUid?, page?, pageSize?)`** — paginated, case-insensitive name search. - **`getComponentSource(uid)`** — the component's definition location `{name, fileName, line, column}` (or `null`). - **`getOwnersStack(uid)`** — the raw JSX owner-stack string (DEV only). - **`getOwnersBranch(uid)`** — the structured owner chain `[{uid, name, type}]`, ordered immediate owner → root (DEV only). ### UIDs Components are addressed by stable `rN` uids, assigned lazily and memoized per fiber (and its alternate), so a component keeps the same uid across re-renders and across every tool. These uids don't survive page reloads.Ruslan Lesiutin · fb2cfa0f · 2026-06-18
- 1.9ETVAdd <ViewTransition> Component (#31975) This will provide the opt-in for using [View Transitions](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API) in React. View Transitions only trigger for async updates like `startTransition`, `useDeferredValue`, Actions or `<Suspense>` revealing from fallback to content. Synchronous updates provide an opt-out but also guarantee that they commit immediately which View Transitions can't. There's no need to opt-in to View Transitions at the "cause" side like event handlers or actions. They don't know what UI will change and whether that has an animated transition described. Conceptually the `<ViewTransition>` component is like a DOM fragment that transitions its children in its own isolate/snapshot. The API works by wrapping a DOM node or inner component: ```js import {ViewTransition} from 'react'; <ViewTransition><Component /></ViewTransition> ``` The default is `name="auto"` which will automatically assign a `view-transition-name` to the inner DOM node. That way you can add a View Transition to a Component without controlling its DOM nodes styling otherwise. A difference between this and the browser's built-in `view-transition-name: auto` is that switching the DOM nodes within the `<ViewTransition>` component preserves the same name so this example cross-fades between the DOM nodes instead of causing an exit and enter: ```js <ViewTransition>{condition ? <ComponentA /> : <ComponentB />}</ViewTransition> ``` This becomes especially useful with `<Suspense>` as this example cross-fades between Skeleton and Content: ```js <ViewTransition> <Suspense fallback={<Skeleton />}> <Content /> </Suspense> </ViewTransition> ``` Where as this example triggers an exit of the Skeleton and an enter of the Content: ```js <Suspense fallback={<ViewTransition><Skeleton /></ViewTransition>}> <ViewTransition><Content /></ViewTransition> </Suspense> ``` Managing instances and keys becomes extra important. You can also specify an explicit `name` property for example for animating the same conceptual item from one page onto another. However, best practices is to property namespace these since they can easily collide. It's also useful to add an `id` to it if available. ```js <ViewTransition name="my-shared-view"> ``` The model in general is the same as plain `view-transition-name` except React manages a set of heuristics for when to apply it. A problem with the naive View Transitions model is that it overly opts in every boundary that *might* transition into transitioning. This is leads to unfortunate effects like things floating around when unrelated updates happen. This leads the whole document to animate which means that nothing is clickable in the meantime. It makes it not useful for smaller and more local transitions. Best practice is to add `view-transition-name` only right before you're about to need to animate the thing. This is tricky to manage globally on complex apps and is not compositional. Instead we let React manage when a `<ViewTransition>` "activates" and add/remove the `view-transition-name`. This is also when React calls `startViewTransition` behind the scenes while it mutates the DOM. I've come up with a number of heuristics that I think will make a lot easier to coordinate this. The principle is that only if something that updates that particular boundary do we activate it. I hope that one day maybe browsers will have something like these built-in and we can remove our implementation. A `<ViewTransition>` only activates if: - If a mounted Component renders a `<ViewTransition>` within it outside the first DOM node, and it is within the viewport, then that ViewTransition activates as an "enter" animation. This avoids inner "enter" animations trigger when the parent mounts. - If an unmounted Component had a `<ViewTransition>` within it outside the first DOM node, and it was within the viewport, then that ViewTransition activates as an "exit" animation. This avoids inner "exit" animations triggering when the parent unmounts. - If an explicitly named `<ViewTransition name="...">` is deep within an unmounted tree and one with the same name appears in a mounted tree at the same time, then both are activated as a pair, but only if they're both in the viewport. This avoids these triggering "enter" or "exit" animations when going between parents that don't have a pair. - If an already mounted `<ViewTransition>` is visible and a DOM mutation, that might affect how it's painted, happens within its children but outside any nested `<ViewTransition>`. This allows it to "cross-fade" between its updates. - If an already mounted `<ViewTransition>` resizes or moves as the result of direct DOM nodes siblings changing or moving around. This allows insertion, deletion and reorders into a list to animate all children. It is only within one DOM node though, to avoid unrelated changes in the parent to trigger this. If an item is outside the viewport before and after, then it's skipped to avoid things flying across the screen. - If a `<ViewTransition>` boundary changes size, due to a DOM mutation within it, then the parent activates (or the root document if there are no more parents). This ensures that the container can cross-fade to avoid abrupt relayout. This can be avoided by using absolutely positioned children. When this can avoid bubbling to the root document, whatever is not animating is still responsive to clicks during the transition. Conceptually each DOM node has its own default that activates the parent `<ViewTransition>` or no transition if the parent is the root. That means that if you add a DOM node like `<div><ViewTransition><Component /></ViewTransition></div>` this won't trigger an "enter" animation since it was the div that was added, not the ViewTransition. Instead, it might cause a cross-fade of the parent ViewTransition or no transition if it had no parent. This ensures that only explicit boundaries perform coarse animations instead of every single node which is really the benefit of the View Transitions model. This ends up working out well for simple cases like switching between two pages immediately while transitioning one floating item that appears on both pages. Because only the floating item transitions by default. Note that it's possible to add manual `view-transition-name` with CSS or `style={{ viewTransitionName: 'auto' }}` that always transitions as long as something else has a `<ViewTransition>` that activates. For example a `<ViewTransition>` can wrap a whole page for a cross-fade but inside of it an explicit name can be added to something to ensure it animates as a move when something relates else changes its layout. Instead of just cross-fading it along with the Page which would be the default. There's more PRs coming with some optimizations, fixes and expanded APIs. This first PR explores the above core heuristic. --------- Co-authored-by: Sebastian "Sebbie" Silbermann <silbermann.sebastian@gmail.com>Sebastian Markbåge · a4d122f2 · 2025-01-08
- 1.7ETV[compiler] Aggregate error reporting, separate eslint rules (#34176) NOTE: this is a merged version of @mofeiZ's original PR along with my edits per offline discussion. The description is updated to reflect the latest approach. The key problem we're trying to solve with this PR is to allow developers more control over the compiler's various validations. The idea is to have a number of rules targeting a specific category of issues, such as enforcing immutability of props/state/etc or disallowing access to refs during render. We don't want to have to run the compiler again for every single rule, though, so @mofeiZ added an LRU cache that caches the full compilation output of N most recent files. The first rule to run on a given file will cause it to get cached, and then subsequent rules can pull from the cache, with each rule filtering down to its specific category of errors. For the categories, I went through and assigned a category roughly 1:1 to existing validations, and then used my judgement on some places that felt distinct enough to warrant a separate error. Every error in the compiler now has to supply both a severity (for legacy reasons) and a category (for ESLint). Each category corresponds 1:1 to a ESLint rule definition, so that the set of rules is automatically populated based on the defined categories. Categories include a flag for whether they should be in the recommended set or not. Note that as with the original version of this PR, only eslint-plugin-react-compiler is changed. We still have to update the main lint rule. ## Test Plan * Created a sample project using ESLint v9 and verified that the plugin can be configured correctly and detects errors * Edited `fixtures/eslint-v9` and introduced errors, verified that the w latest config changes in that fixture it correctly detects the errors * In the sample project, confirmed that the LRU caching is correctly caching compiler output, ie compiling files just once. Co-authored-by: Mofei Zhang <feifei0@meta.com>Joseph Savona · 7d29ecbe · 2025-08-21
- 1.6ETV[compiler] Add snap subcommand to minimize a test input (#35663) Snap now supports subcommands 'test' (default) and 'minimize`. The minimize subcommand attempts to minimize a single failing input fixture by incrementally simplifying the ast so long as the same error occurs. I spot-checked it and it seemed to work pretty well. This is intended for use in a new subagent designed for investigating bugs — fixture simplification is an important part of the process and we can automate this rather than light tokens on fire. Example Input: ```js function Component(props) { const x = []; let result; for (let i = 0; i < 10; i++) { if (cond) { try { result = {key: bar([props.cond && props.foo])}; } catch (e) { console.log(e); } } } x.push(result); return <Stringify x={x} />; } ``` Command output: ``` $ yarn snap minimize --path .../input.js Minimizing: .../input.js Minimizing................ --- Minimized Code --- function Component(props) { try { props && props; } catch (e) {} } Reduced from 16 lines to 5 lines ``` This demonstrates things like: * Removing one statement at at time * Replacing if/else with the test, consequent, or alternate. Similar for other control-flow statements including try/catch * Removing individual array/object expression properties * Replacing single-value array/object with the value * Replacing control-flow expression (logical, consequent) w the test or left/right values * Removing call arguments * Replacing calls with a single argument with the argument * Replacing calls with multiple arguments with an array of the arguments * Replacing optional member/call with non-optional versions * Replacing member expression with the object. If computed, also try replacing w the key * And a bunch more strategies, see the codeJoseph Savona · d4a325df · 2026-02-03
- 1.5ETV[Flight] Add more DoS mitigations to Flight Reply, and harden Flight (#35632) This fixes security vulnerabilities in Server Functions. --------- Co-authored-by: Sebastian Markbåge <sebastian@calyptus.eu> Co-authored-by: Josh Story <josh.c.story@gmail.com> Co-authored-by: Janka Uryga <lolzatu2@gmail.com> Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>Hendrik Liebau · 10680271 · 2026-01-26
- 1.4ETV[DevTools] Use use() instead of throwing a Promise in Caches (#34033)Sebastian Markbåge · 5d7e8b90 · 2025-07-29
- 1.4ETVAdd Flight SSR benchmark fixture (#36180) This PR adds a benchmark fixture for measuring the performance overhead of the React Server Components (RSC) Flight rendering compared to plain Fizz server-side rendering. ### Motivation Performance discussions around RSC (e.g. #36143, #35125) have highlighted the need for reproducible benchmarks that accurately measure the cost that Flight adds on top of Fizz. This fixture provides multiple benchmark modes that can be used to track performance improvements across commits, compare Node vs Edge (web streams) overhead, and identify bottlenecks in Flight serialization and deserialization. ### What it measures The benchmark renders a dashboard app with ~25 components (16 client components), 200 product rows with nested data (~325KB Flight payload), and ~250 Suspense boundaries in the async variant. It compares 8 render variants: Fizz-only and Flight+Fizz, across Node and Edge stream APIs, with both synchronous and asynchronous apps. ### Benchmark modes - **`yarn bench`** runs a sequential in-process benchmark with realistic Flight script injection (tee + `TransformStream`/`Transform` buffered injection), matching what real frameworks do when inlining the RSC payload into the HTML response for hydration. - **`yarn bench:bare`** runs the same benchmark without script injection, isolating the React-internal rendering cost. This is best for tracking changes to Flight serialization or Fizz rendering. - **`yarn bench:server`** starts an HTTP server and uses `autocannon` to measure real req/s at `c=1` and `c=10`. The `c=1` results provide a clean signal for tracking React-internal changes, while `c=10` reflects throughput under concurrent load. - **`yarn bench:concurrent`** runs an in-process concurrent benchmark with 50 in-flight renders via `Promise.all`, measuring throughput without HTTP overhead. - **`yarn bench:profile`** collects CPU profiles via the V8 inspector and reports the top functions by self-time along with GC pause data. - **`yarn start`** starts the HTTP server for manual browser testing. Appending `.rsc` to any Flight URL serves the raw Flight payload. ### Key findings during development On Node 22, the Flight+Fizz overhead compared to Fizz-only rendering is roughly: - **Without script injection** (`bench:bare`): ~2.2x for sync, ~1.3x for async - **With script injection** (`bench:server`, c=1): ~2.9x for sync, ~1.8x for async - **Edge vs Node** adds another ~30% for sync and ~10% for async, driven by the stream plumbing for script injection (tee + `TransformStream` buffering) The async variant better represents real-world applications where server components fetch data asynchronously. Its lower overhead reflects the fact that Flight serialization and Fizz rendering can overlap with I/O wait times, making the added Flight cost a smaller fraction of total request time. The benchmark also revealed that the Edge vs Node gap is negligible for Fizz-only rendering (~1-2%) but grows to ~15% for Flight+Fizz sync even without script injection. With script injection (tee + `TransformStream` buffering), the gap roughly doubles to ~30% for sync. The async variants show smaller gaps (~5% without, ~10% with injection).Hendrik Liebau · 1b45e243 · 2026-04-02
- 1.3ETVAdd parentEnter/parentExit props to ViewTransition (#36690) An alternative to https://github.com/facebook/react/pull/36135 ___ Adds experimental support for `parentEnter` and `parentExit` on nested `<ViewTransition>` components, so descendants can animate when an ancestor boundary enters or exits. This is gated behind the `enableViewTransitionParentEnterExit` feature flag. Addresses the use case of animating individual items in a list (such as sliding inactive feed posts off-screen) when a parent `<ViewTransition>` is the one being added or removed during the update. Today, `exit`/ `enter` only fire on the `<ViewTransition>` that was directly mounted or unmounted. Nested boundaries in the same subtree are not visited for their own `exit`/`enter` when the whole tree goes away as one unit, which is usually what you want. But some cases need an explicit opt-in to nested animations. This PR adds `parentEnter`/`parentExit`, and their handlers `onParentEnter`/`onParentExit`. When an ancestor runs a real `enter` or `exit`, React walks descendants and activates boundaries that define the nested props. This only continues through `<ViewTransition>` nodes that define `parentEnter` / `parentExit` / `onParentEnter` / `onParentExit` / `onGestureParentEnter` / `onGestureParentExit`, otherwise the chaining stops. A boundary’s own `enter`/`exit` still do not run when only an ancestor animates. So it is possible to have different animations on the same `<ViewTransition>` for `enter` vs `parentEnter`. ```jsx function ExampleOnAncestorExit() { return ( // This boundary exits — starts the parentExit walk <ViewTransition exit="panel-exit"> <div> {/* ✓ Activates: parentExit set. Walk continues inside */} <ViewTransition parentExit="slide-out"> <div> {/* ✗ parentEnter is not consulted on an exit walk */} <ViewTransition parentEnter="slide-in"> ... </ViewTransition> {/* ✗ Chain broken: no parentExit or onParentExit */} <ViewTransition> <div> {/* ✗ Never reached on this path, blocked by parent above */} <ViewTransition parentExit="slide-out"> ... </ViewTransition> </div> </ViewTransition> {/* ✓ Handler-only chain: onParentExit continues the walk */} <ViewTransition onParentExit={() => animateOut()}> <ViewTransition onParentExit={() => animateDeepOut()}> ... </ViewTransition> </ViewTransition> {/* ✓ Activates: sibling under the chain */} <ViewTransition parentExit="slide-out"> ... </ViewTransition> </div> </ViewTransition> </div> </ViewTransition> ); } ```Jack Pope · ec0fca31 · 2026-07-01
- 1.3ETV[assert helpers] react-dom (pt3) (#31983) moar assert helpers this finishes all of react-dom except the server integration tests which are tricky to convertRicky · 03e4ec2d · 2025-01-05
- 1.2ETV[compiler] Migrate CompilerError.invariant to new CompilerDiagnostic infra (#34403) Mechanical PR to migrate existing invariants to use the new CompilerDiagnostic infra @josephsavona added. Will tackle the others at a later time. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34403). * #34409 * #34404 * __->__ #34403lauren · 474f2584 · 2025-09-06
- 1.2ETV[assert helpers] react-dom (pt 1) (#31897) Converts ~half of react-dom testsRicky · a7c898d8 · 2025-01-02
- 1.0ETV[compiler] Improve IIFE inlining (#33726) We currently inline IIFEs by creating a temporary and a labeled block w the original code. The original return statements turn into an assignment to the temporary and break out of the label. However, many cases of IIFEs are due to inlining of manual `useMemo()`, and these cases often have only a single return statement. Here, the output is cleaner if we avoid the temporary and label - so that's what we do in this PR. Note that the most complex part of the change is actually around ValidatePreserveExistingMemo - we have some logic to track the IIFE temporary reassignmetns which needs to be updated to handle the simpler version of inlining. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33726). * __->__ #33726 * #33725Joseph Savona · 956d770a · 2025-07-08
- 1.0ETV[Flight] Add 'pending_weak' to Flight thenable protocol (#37154) Added behind a new experimental flag, `enableFlightWeakThenables`. Adds a new thenable status to the Flight protocol: `'pending_weak'`. Unlike a regular pending thenable, a weak thenable does not block the stream from closing. If it settles while the stream is still open, its value is emitted like a normal pending thenable. Otherwise its reference is left unfulfilled and on the client it stays forever pending, without erroring, even when the connection closes. It's up to the client to handle the unresolved promise in an appropriate way. The motivating use case is being able to encode metadata about a Flight stream into the response itself. For example, a framework might want to track whether a page varies by search params. It could represent this in the response as a `Promise<boolean>` that resolves to `true` as soon as the component being rendered in the stream accesses search params. If the thenable never resolves by the time the stream closes, then the client knows that no search params were ever accessed. In the future we could add a higher-level API for encoding this kind of information. For now, we intentionally start with the low-level primitive so frameworks can experiment in userspace without adding significantly to React's surface area. Internally, Flight already uses its own private thenable statuses, like `'resolved_model'`, and the protocol is designed to treat any status besides `'fulfilled'` and `'rejected'` as equivalent to `'pending'`, so `'pending_weak'` slots into the existing machinery. On the wire, a weak reference is encoded as `$w<id>`, next to `$@<id>` for regular promises, so the client knows its row may intentionally never arrive. On the client, a weak reference behaves like any other pending promise until the response closes; then, instead of erroring, it is left forever pending.Andrew Clark · 9b5b4d51 · 2026-07-31
- 1.0ETVInferEffectDeps takes a React.AUTODEPS sigil (#33799) --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33799). * #33800 * __->__ #33799Jordan Brown · dffacc7b · 2025-07-17
- 1.0ETV[compiler] Upstream experimental flow integration (#34121) all credit on the Flood/ code goes to @mvitousek and @jbrown215, i'm just the one upstreaming itJoseph Savona · c403a7c5 · 2025-08-06
- 1.0ETV[Fizz] Finalize postponed nextSegmentId after the prelude flush (#36779) `getPostponedState` snapshots `request.nextSegmentId` at `onAllReady`, before the Fizz stream is flowing. At this point we have visited all Suspense boundaries and know which ones suspended by user code or not. However, only when the stream is flowing are we counting the size of each boundary. When we detect large boundaries, we suspend them i.e. we outline them instead of keeping them inline. This results in more segments being written while the postponed state holds a stale count. We now keep a reference to the returned postponed state and mutate the segment IDs when we outline. That way serializing `postponed` after the `prelude` has flushed writes the latest postponed state. The current API design means that you can potentially serialize stale postponed state. We're considering a redesign to make these issues impossible (e.g. https://github.com/react/react/pull/36815). For now, the postponed state should only be serialized or passed onto a `resume` once the `prelude` has flushed e.g.: ```js const { createWriteStream, writeFileSync } = require('node:fs'); const { createWriteStream } = require('node:stream'); const { prelude, postponed } = prenderToNodeStream(...) // serializing `postponed` now would write a stale state. // serialize prelude const destination = createWriteStream('prelude.html') prelude.pipe(destination) await finished(prelude) // now we can serialize postponed writeFileSync('postponed.json', JSON.stringify(postponed)) ``` --------- Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>Jude Gao · b1786c31 · 2026-06-18
- 1.0ETVAdd ref to Fragment (#32465) *This API is experimental and subject to change or removal.* This PR is an alternative to https://github.com/facebook/react/pull/32421 based on feedback: https://github.com/facebook/react/pull/32421#pullrequestreview-2625382015 . The difference here is that we traverse from the Fragment's fiber at operation time instead of keeping a set of children on the `FragmentInstance`. We still need to handle newly added or removed child nodes to apply event listeners and observers, so we treat those updates as effects. **Fragment Refs** This PR extends React's Fragment component to accept a `ref` prop. The Fragment's ref will attach to a custom host instance, which will provide an Element-like API for working with the Fragment's host parent and host children. Here I've implemented `addEventListener`, `removeEventListener`, and `focus` to get started but we'll be iterating on this by adding additional APIs in future PRs. This sets up the mechanism to attach refs and perform operations on children. The FragmentInstance is implemented in `react-dom` here but is planned for Fabric as well. The API works by targeting the first level of host children and proxying Element-like APIs to allow developers to manage groups of elements or elements that cannot be easily accessed such as from a third-party library or deep in a tree of Functional Component wrappers. ```javascript import {Fragment, useRef} from 'react'; const fragmentRef = useRef(null); <Fragment ref={fragmentRef}> <div id="A" /> <Wrapper> <div id="B"> <div id="C" /> </div> </Wrapper> <div id="D" /> </Fragment> ``` In this case, calling `fragmentRef.current.addEventListener()` would apply an event listener to `A`, `B`, and `D`. `C` is skipped because it is nested under the first level of Host Component. If another Host Component was appended as a sibling to `A`, `B`, or `D`, the event listener would be applied to that element as well and any other APIs would also affect the newly added child. This is an implementation of the basic feature as a starting point for feedback and further iteration.Jack Pope · 6aa8254b · 2025-03-12
- 0.9ETV[compiler] Avoid failing builds when import specifiers conflict or shadow vars (#32663) Avoid failing builds when imported function specifiers conflict by using babel's `generateUid`. Failing a build is very disruptive, as it usually presents to developers similar to a javascript parse error. ```js import {logRender as _logRender} from 'instrument-runtime'; const logRender = () => { /* local conflicting implementation */ } function Component_optimized() { _logRender(); // inserted by compiler } ``` Currently, we fail builds (even in `panicThreshold:none` cases) when import specifiers are detected to conflict with existing local variables. The reason we destructively throw (instead of bailing out) is because (1) we first generate identifier references to the conflicting name in compiled functions, (2) replaced original functions with compiled functions, and then (3) finally check for conflicts. When we finally check for conflicts, it's too late to bail out. ```js // import {logRender} from 'instrument-runtime'; const logRender = () => { /* local conflicting implementation */ } function Component_optimized() { logRender(); // inserted by compiler } ```mofeiZ · c61e75b7 · 2025-03-24