Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

babel import-plugin still rewrites react-native-web internals, causing a circular-import crash on web (incomplete fix of #196 / #202)

未關閉
#380 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 3 天內回覆

還沒有人認領這個 Issue。

評估

難度
4/5
預估耗時
1-2 天
新手友好度
48/100
Issue 類型
缺陷
描述清晰度
基本清楚
活躍度
冷清
技術堆疊
react-native, typescript

研究方向

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.

由索引模型根據 Issue 內容生成。

描述

auto-triaged bug confirmed
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:

  1. Something touches Animated → react-native-web/dist/vendor/react-native/Animated/Animated.js loads AnimatedFlatList.js.
  2. AnimatedFlatList.js imports ../../../../exports/FlatList → resolves into react-native-web/dist → babel rewrites it to react-native-css/components/FlatList. (The resolver's vendor exclusion doesn't help: it checks the target path, and the target here is exports/FlatList, not a vendor file. The babel plugin rewrites the specifier before the resolver would matter anyway.)
  3. react-native-css/components/FlatList imports react-native → react-native-web/dist/index.js.
  4. The index's own export { default as FlatList } from './exports/FlatList' was also babel-rewritten to react-native-css/components/FlatList — which is the module currently mid-initialization in step 3 → its partial exports have no default → 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 existing isFromThisModule skip so files inside react-native-web are 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 to webResolver (mirrors nativeResolver's isReactNativeIndex guard):
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
  1. Create an Expo SDK 57 app (create-expo-app, default template — it already uses Animated via its demo screens; any code path that touches react-native-web's Animated export triggers the bug).
  2. Install NativeWind v5 preview ([email protected] + [email protected]) with the standard withNativewind metro config and nativewind/babel preset.
  3. expo start, open the web target.
  4. 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.

主要語言
TypeScript
星號
166
分支
45
平均合併
13 天 14 小時
30 天內合併 PR
1

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 沒有 Pull Request 範本
  • 閱讀貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

nativewind/react-native-css 的其他 Issue

查看 nativewind/react-native-css 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。