Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの 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 件 担当者 0 名 GitHub で見る

メンテナーはふだん 3 日以内に返信

まだ誰も着手していません。

評価

難易度
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時間
マージ済み PR(30日)
1

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

nativewind/react-native-css のほかの issue

nativewind/react-native-css の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。