@react-native/babel-preset applies transform-destructuring unconditionally under Hermes — semantic divergence breaks three.js TSL (crashes every InstancedMesh on WebGPU)
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 55/100
- Issue-Typ
- Bug
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- javascript, react-native, three.js
- Bereich
- build-system, mobile, tooling
Rechercherichtung
Beginne in packages/react-native-babel-preset/src/configs/main.js, insbesondere bei der Liste der immer aktivierten Plugins um Zeile 122, und reproduziere die Transformation mit dem array-gestützten Proxy-Beispiel aus dem Issue. Vergleiche die bereits vorhandenen Konfigurationsmuster für Hermes und Nicht-Hermes; abgeschlossen ist die Aufgabe, wenn das Preset entweder die semantische Abweichung für Hermes vermeidet oder einen bestätigten Grund dokumentiert, die Transformation beizubehalten, und das Verhalten der Toolchain durch einen geeigneten Test abgedeckt ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Description
@react-native/babel-preset pushes @babel/plugin-transform-destructuring unconditionally — including for Hermes targets (packages/react-native-babel-preset/src/configs/main.js, the always-on plugin list; verified in 0.81.4 at src/configs/main.js:122). Hermes supports array/object destructuring natively, so for Hermes builds the transform is (a) redundant bytecode and (b) a semantic hazard, because downleveled destructuring is not perfectly equivalent to native destructuring.
The concrete divergence: native array destructuring always goes through the iterator protocol, while Babel's _slicedToArray helper short-circuits via _arrayWithHoles — if (Array.isArray(r)) return r; — and then indexes positionally. For a Proxy over an array (Array.isArray pierces to the target) whose get trap serves a custom Symbol.iterator but does not answer positional reads, the two compile outputs produce different values: iterator yields the real elements, indexing yields undefined.
That exotic-sounding object is shipping in one of the most popular 3D libraries: three.js's TSL shader system passes Fn arguments through exactly such a Proxy, and three's own sources destructure it (src/nodes/accessors/Instance.js: Fn( ( [ instancedMesh ] ) => { const { instanceMatrix, instanceColor } = instancedMesh; ... } )). Metro rewrites three's code with this transform, so on device the body receives undefined and every React Native app using three.js WebGPU (react-native-webgpu, Dawn/Vulkan) with an InstancedMesh crashes on the first rendered frame:
TypeError: Cannot read property 'instanceMatrix' of undefined
at ... setupOutput / getOutputNode / build / flowNodeFromShaderStage / ... / render
The same pattern arms skinning(), batch() and morphReference() — i.e. skinned meshes, batched meshes and morph targets are equally affected. Nothing surfaces in Node/browser tests because those run untransformed code; the failure exists only in the Metro-bundled app.
Ask
Consider making transform-destructuring conditional on the engine target (skipped for Hermes, as several other transforms already are engine-aware), or documenting why it must stay unconditional. Cross-filed with the two neighboring projects, since each owns a slice of the collision:
- three.js (Proxy should honor positional reads): https://github.com/mrdoob/three.js/issues/34227
- Babel (
_arrayWithHolesfast path vs custom iterators on array-backed Proxies): link to follow in a comment
Steps to reproduce
- Bare RN 0.81.4 app (Hermes, new arch) +
react-native-webgpu0.8.2 +three0.185.1 - Render any scene containing a
THREE.InstancedMeshwithWebGPURenderer - First frame throws
TypeError: Cannot read property 'instanceMatrix' of undefined
A toolchain-only demonstration (no device needed): run @react-native/babel-preset over const fn = ([a]) => a; and observe the _slicedToArray output; feed it an array-backed Proxy with a custom Symbol.iterator in its get trap and no index handling — native semantics return the element, transformed semantics return undefined.
React Native Version
0.81.4
Affected Platforms
Runtime: Android (verified on device: Android 15, Hermes release bundle, Dawn/Vulkan). iOS untested but the transform is platform-independent.
Output of npx @react-native-community/cli info
Not attached — the report is toolchain-level (@react-native/babel-preset 0.81.4, @babel/plugin-transform-destructuring 7.29.7, @babel/runtime 7.29.7); happy to add on request.
- Vorherrschende Sprache
- C++
- Sterne
- 127k
- Forks
- 25.3k
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus react/react-native
-
Needs: Author Feedback Needs: Repro
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
react/react-native#58659 · 1 Kommentar ·
-
Needs: Author Feedback Needs: Repro
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 92/100
react/react-native#58621 · 1 Kommentar ·
-
Needs: Author Feedback Needs: Repro
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 85/100
react/react-native#58610 · 1 Kommentar ·
-
Needs: Triage :mag:
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
react/react-native#58565 · 1 Kommentar · 2 Reaktionen ·
-
Needs: Author Feedback Needs: Repro
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 88/100
react/react-native#58555 · 5 Kommentare · 2 Reaktionen ·
Alle Issues in react/react-native
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
-
good first issue
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
ros2/message_filters#338 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
subsurface/subsurface#4984 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
flutter-webrtc/flutter-webrtc#2206 ·
-
litertlm-android AAR ships no consumer ProGuard rules → "mid == null" SIGABRT in minified apps Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
google-ai-edge/LiteRT-LM#3739 ·