Skip to content

fix(metro-transformer-oxc): handle leading/trailing comments#4041

Merged
tido64 merged 2 commits intomainfrom
tido/transformer-oxc/fix-crash
Mar 24, 2026
Merged

fix(metro-transformer-oxc): handle leading/trailing comments#4041
tido64 merged 2 commits intomainfrom
tido/transformer-oxc/fix-crash

Conversation

@tido64
Copy link
Member

@tido64 tido64 commented Mar 24, 2026

Description

Handle differences in how leading/trailing comments are parsed in oxc-parser vs Babel.

Specifically, oxc-parser skips comments and sets the program node's start/end to >0 and <length. This causes Babel to trip because it assumes start=0 and end=length:

Error stack
TypeError: /~/node_modules/.store/react-native-svg-virtual-fceb68471e/package/src/elements/Shape.tsx: Cannot read properties of undefined (reading 'name')
    at advanceToPos (/~/node_modules/.store/metro-source-map-npm-0.83.3-ef51438b2d/package/src/generateFunctionMap.js:100:33)
    at pushFrame (/~/node_modules/.store/metro-source-map-npm-0.83.3-ef51438b2d/package/src/generateFunctionMap.js:115:5)
    at Object.enter (/~/node_modules/.store/metro-source-map-npm-0.83.3-ef51438b2d/package/src/generateFunctionMap.js:141:7)
    at PluginPass.pre (/~/node_modules/.store/metro-source-map-npm-0.83.3-ef51438b2d/package/src/generateFunctionMap.js:73:15)
    at PluginPass.sync (/~/node_modules/.store/@babel-core-npm-7.29.0-a74bfc561b/package/lib/gensync-utils/async.js:30:25)
    at PluginPass.sync (/~/node_modules/.store/gensync-npm-1.0.0-beta.2-224666d72f/package/index.js:182:19)
    at PluginPass.<anonymous> (/~/node_modules/.store/gensync-npm-1.0.0-beta.2-224666d72f/package/index.js:210:24)
    at Generator.next (<anonymous>)
    at transformFile (/~/node_modules/.store/@babel-core-npm-7.29.0-a74bfc561b/package/lib/transformation/index.js:75:19)
    at transformFile.next (<anonymous>)
    at run (/~/node_modules/.store/@babel-core-npm-7.29.0-a74bfc561b/package/lib/transformation/index.js:25:12)
    at run.next (<anonymous>)
    at /~/node_modules/.store/@babel-core-npm-7.29.0-a74bfc561b/package/lib/transform-ast.js:23:33
    at Generator.next (<anonymous>)
    at evaluateSync (/~/node_modules/.store/gensync-npm-1.0.0-beta.2-224666d72f/package/index.js:251:28)
    at sync (/~/node_modules/.store/gensync-npm-1.0.0-beta.2-224666d72f/package/index.js:89:14)
    at stopHiding - secret - don't use this - v1 (/~/node_modules/.store/@babel-core-npm-7.29.0-a74bfc561b/package/lib/errors/rewrite-stack-trace.js:47:12)
    at transformFromAstSync (/~/node_modules/.store/@babel-core-npm-7.29.0-a74bfc561b/package/lib/transform-ast.js:41:83)
    at Object.transform (/~/incubator/metro-transformer-oxc/lib/index.js:60:57)
    at transformJSWithBabel (/~/node_modules/.store/metro-transform-worker-npm-0.83.3-e46eb75b1f/package/src/index.js:350:45)
    at Object.transform (/~/node_modules/.store/metro-transform-worker-npm-0.83.3-e46eb75b1f/package/src/index.js:495:16)
    at transformFile (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/Worker.flow.js:67:36)
    at Object.transform (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/Worker.flow.js:42:10)
    at WorkerFarm.transform (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/WorkerFarm.js:44:39)
    at Transformer.transformFile (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/Transformer.js:124:32)
    at async Object.transform (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/lib/transformHelpers.js:137:12)
    at async transform (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/Graph.js:170:26)
    at async visit (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/buildSubgraph.js:80:29)
    at async Promise.all (index 1)
    at async visit (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/buildSubgraph.js:90:5)
    at async Promise.all (index 0)
    at async visit (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/buildSubgraph.js:90:5)
    at async Promise.all (index 6)
    at async visit (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/buildSubgraph.js:90:5)
    at async Promise.all (index 2)
    at async visit (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/buildSubgraph.js:90:5)
    at async Promise.all (index 0)
    at async buildSubgraph (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/buildSubgraph.js:105:3)
    at async Graph._buildDelta (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/Graph.js:163:22)
    at async Graph.initialTraverseDependencies (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/Graph.js:146:19)
    at async DeltaCalculator._getChangedDependencies (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/DeltaCalculator.js:155:25)
    at async DeltaCalculator.getDelta (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler/DeltaCalculator.js:72:16)
    at async DeltaBundler.buildGraph (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/DeltaBundler.js:42:5)
    at async IncrementalBundler.buildGraphForEntries (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/IncrementalBundler.js:90:19)
    at async IncrementalBundler.buildGraph (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/IncrementalBundler.js:170:19)
    at async Server.build (/~/node_modules/.store/metro-npm-0.83.3-6f86736a59/package/src/Server.js:235:32)
    at async buildBundle (/~/packages/metro-service/lib/bundle/bundle-0.71.js:26:29)
    at async bundle (/~/packages/metro-service/lib/bundle.js:80:12)
    at async metroBundle (/~/packages/cli/lib/bundle/metro.js:72:5) {
  type: 'TransformError',
  lineNumber: 0
}

Test plan

Add react-native-svg and use it in the test app:

diff --git a/packages/test-app/package.json b/packages/test-app/package.json
index 763400430..e7cf5ebac 100644
--- a/packages/test-app/package.json
+++ b/packages/test-app/package.json
@@ -39,7 +39,8 @@
   "dependencies": {
     "@react-native-webapis/web-storage": "workspace:*",
     "react": "19.2.0",
-    "react-native": "^0.83.0"
+    "react-native": "^0.83.0",
+    "react-native-svg": ">=15.15.1 <15.15.3"
   },
   "devDependencies": {
     "@babel/core": "^7.20.0",
diff --git a/packages/test-app/src/App.native.tsx b/packages/test-app/src/App.native.tsx
index 204d42994..f15471f68 100644
--- a/packages/test-app/src/App.native.tsx
+++ b/packages/test-app/src/App.native.tsx
@@ -1,6 +1,7 @@
 import { acquireTokenWithScopes } from "@rnx-kit/react-native-auth";
 import React, { useEffect, useState } from "react";
 import { Pressable, Text } from "react-native";
+import { Rect, Svg } from "react-native-svg";
 import manifest from "../app.json";
 import { Feature } from "./Feature";
 import { Home } from "./Home";
@@ -53,6 +54,18 @@ export function App({ concurrentRoot }: { concurrentRoot?: boolean }) {
   }, []);
   return (
     <Home concurrentRoot={concurrentRoot}>
+      <Svg width="200" height="60">
+        <Rect
+          x="5%"
+          y="5%"
+          width="90%"
+          height="90%"
+          fill="rgb(0,0,255)"
+          strokeWidth="3"
+          stroke="rgb(0,0,0)"
+          strokeDasharray="5,10"
+        />
+      </Svg>
       <Feature value={localStorageStatus}>window.localStorage</Feature>
       <Separator />
       <Button onPress={startAcquireToken}>Acquire Token</Button>

Then bundle the app (debug or release doesn't matter).

@tido64 tido64 force-pushed the tido/transformer-oxc/fix-crash branch from 9811522 to fc61afb Compare March 24, 2026 09:31
@tido64 tido64 merged commit 8c7279a into main Mar 24, 2026
15 checks passed
@tido64 tido64 deleted the tido/transformer-oxc/fix-crash branch March 24, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants