babel import-plugin still rewrites react-native-web internals, causing a circular-import crash on web (incomplete fix of #196 / #202)
Maintainer thường phản hồi trong vòng 3 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- react-native, typescript
- Lĩnh vực
- build-system, frontend
Hướng nghiên cứu
Start in src/babel/import-plugin.ts, at isFromThisModule and parseReactNativeWebSource, to see how relative imports inside react-native-web/dist get rewritten. Then compare webResolver in src/metro/resolver.ts with nativeResolver, which already skips rewriting when the origin is react-native/index.js. Done means a web bundle with Animated loads without the circular-import TypeError; the reporter has no public repro, so you will need to build one from the steps in the issue first.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Before submitting a new issue
- I tested using the latest version of the library, as the bug might be already fixed.
- I tested using a supported version of react native.
- I checked for possible duplicate issues, with possible answers.
Bug summary
This is a follow-up to #196 — the fix in #202 is incomplete, so the react-native-web circular-import crash still reproduces on web with [email protected].
On web, the app crashes at bundle load time:
Web ERROR [TypeError: Cannot read properties of undefined (reading 'default')]
Code: index.js
35 | export { default as Button } from './exports/Button';
36 | export { default as CheckBox } from './exports/CheckBox';
> 37 | export { default as FlatList } from './exports/FlatList';
Call Stack
<global> (react-native-web/dist/index.js:37)
<global> (react-native-css/dist/commonjs/components/FlatList.js:17)
<global> (react-native-web/dist/vendor/react-native/Animated/components/AnimatedFlatList.js:12)
<global> (react-native-web/dist/vendor/react-native/Animated/Animated.js:13)
(In a production bundle this surfaces as can't access property "default", _exportsFlatList2 is undefined.)
Root cause
There are two layers that rewrite react-native(-web) imports to react-native-css/components/*: the metro webResolver (src/metro/resolver.ts) and the babel import-plugin (src/babel/import-plugin.ts). #202 only touched the resolver, and only by excluding resolution targets inside react-native-web/dist/vendor (plus VirtualizedList). Neither layer excludes origins inside react-native-web, and the babel plugin was not changed at all.
The babel plugin's parseReactNativeWebSource resolves relative import specifiers against the current filename and rewrites anything that lands inside react-native-web/dist. So react-native-web's own internal imports get rewritten, which creates the cycle:
- Something touches
Animated→react-native-web/dist/vendor/react-native/Animated/Animated.jsloadsAnimatedFlatList.js. AnimatedFlatList.jsimports../../../../exports/FlatList→ resolves intoreact-native-web/dist→ babel rewrites it toreact-native-css/components/FlatList. (The resolver's vendor exclusion doesn't help: it checks the target path, and the target here isexports/FlatList, not a vendor file. The babel plugin rewrites the specifier before the resolver would matter anyway.)react-native-css/components/FlatListimportsreact-native→react-native-web/dist/index.js.- The index's own
export { default as FlatList } from './exports/FlatList'was also babel-rewritten toreact-native-css/components/FlatList— which is the module currently mid-initialization in step 3 → its partial exports have nodefault→ crash.
Note the native side already has exactly the guard that's missing here: nativeResolver skips rewriting when the origin is react-native/index.js.
Suggested fix (verified locally via pnpm patch against the published dist):
src/babel/import-plugin.ts— extend the existingisFromThisModuleskip so files insidereact-native-webare never rewritten:
function isFromThisModule(filename: string) {
return (
filename.startsWith(thisModuleDist) ||
filename.startsWith(thisModuleSrc) ||
// react-native-web internals must keep their raw imports, otherwise
// rnw/index -> css component -> "react-native" -> rnw/index cycles
filename.includes(`${sep}react-native-web${sep}`)
);
}
src/metro/resolver.ts— add the equivalent origin guard towebResolver(mirrorsnativeResolver'sisReactNativeIndexguard):
export function webResolver(resolver, context, moduleName, platform) {
const resolution = resolver(context, moduleName, platform);
if (
isFromThisModule(context.originModulePath) ||
// Don't rewrite react-native-web's own internal imports
context.originModulePath.includes(`${sep}react-native-web${sep}`) ||
resolution.type !== "sourceFile" ||
...
With both guards in place: userland imports of react-native / react-native-web still resolve to the wrapped components (via the resolver / babel rewrite of their imports), the wrappers still receive the raw react-native-web implementations, the cycle is gone, and the app renders on web. Android/native is unaffected. Happy to open a PR if that helps.
Library version
3.0.7
Environment info
expo: ~57.0.7 (SDK 57 default template + expo-router)
react-native: 0.86.0
react: 19.2.3
react-native-web: ~0.21.0 (0.21.2 installed)
nativewind: 5.0.0-preview.4
react-native-css: 3.0.7
node: 24.15.0, pnpm: 11.10.0, OS: Linux
React Compiler enabled, bundling via `expo start` (dev) and `expo export` (prod) — both crash identically
Steps to reproduce
- Create an Expo SDK 57 app (
create-expo-app, default template — it already usesAnimatedvia its demo screens; any code path that touches react-native-web'sAnimatedexport triggers the bug). - Install NativeWind v5 preview (
[email protected]+[email protected]) with the standardwithNativewindmetro config andnativewind/babelpreset. expo start, open the web target.- The bundle crashes at load with the error above before anything renders.
Reproducible example repository
The full root-cause analysis and a verified fix are included above; my project is private, but I can extract a minimal public repro from the steps above if needed.
- Ngôn ngữ chính
- TypeScript
- Star
- 166
- Fork
- 45
- Merge trung bình
- 13 ngày 14 giờ
- Pull request đã merge (30 ngày)
- 1
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của nativewind/react-native-css
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
nativewind/react-native-css#545 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
nativewind/react-native-css#544 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
nativewind/react-native-css#543 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
nativewind/react-native-css#540 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
nativewind/react-native-css#538 ·
Maintainer thường phản hồi trong vòng 3 ngày
Tất cả issue của nativewind/react-native-css
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Graphify-Labs/graphify#4860 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
sveltejs/eslint-plugin-svelte#1615 ·
Maintainer thường phản hồi trong vòng 7 ngày
-
Parallel reticle_verify opens per-flow leases without the source lease's ignoreHTTPSErrorsCó thể đã có người làm @as992949791 đã nhận hôm nay. Đang mởgood first issue help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
reticlehq/reticle#2033 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày