react / react/react-native

should explicitly declare type:commonjs since Node experimental-detect-module is on by default

未关闭
#50,052 17 条评论 10 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Needs: Attention Needs: Version Info
主要语言
C++
星标
127k
派生
25.3k
平均合并
1 天 23 小时
30 天内合并 PR
4

描述

Description

With recent Node versions a vitest test suite which tries to load react-native will load it as a module rather than as commonjs, and that will lead to SyntaxError: Unexpected token 'typeof'

This happens for all Node versions that have experimental-detect-module set to true by default, that is Node 20.19 and later, Node 22.7 and later, Node 23 (all versions) etc.

What I think happens is that based on the index.js file, node detects that React-Native is ESM and tries to run it as a module.

One workaround is to configure this script (see npm run dev below)

"dev": "NODE_OPTIONS='--no-experimental-detect-module' vitest"

Steps to reproduce
  1. checkout the reproduction repo, run npm install
  2. switch to a recent node version like 20.19 or later, 22.7 or later, 23
  3. npm run test (which executes vitest) will fail with SyntaxError: Unexpected token 'typeof'. npm run dev (which also executes vitest, but with the flag above) works for all node versions >= 20 (earlier node versions do not recognize the flag). npm run expo works for any Node version supported by React Native.
  4. edit node_modules/react-native/package.json and add "type":"commonjs". This will help npm run test work as expected.
React Native Version

0.77.1

Affected Platforms

Build - MacOS, Other (please specify)

Output of npx @react-native-community/cli info
System:
  OS: macOS 14.2.1
  CPU: (8) arm64 Apple M1
  Memory: 265.11 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 23.10.0
    path: ~/.nvm/versions/node/v23.10.0/bin/node
  Yarn: Not Found
  npm:
    version: 10.9.2
    path: ~/.nvm/versions/node/v23.10.0/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods: Not Found
SDKs:
  iOS SDK: Not Found
  Android SDK: Not Found
IDEs:
  Android Studio: Not Found
  Xcode:
    version: /undefined
    path: /usr/bin/xcodebuild
Languages:
  Java: Not Found
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.3.1
    wanted: ^18.3.1
  react-native:
    installed: 0.77.1
    wanted: ^0.77.*
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

info React Native v0.78.0 is now available (your project is running on v0.77.1).
info Changelog: https://github.com/facebook/react-native/releases/tag/v0.78.0
info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.77.1&to=0.78.0
info For more info, check out "https://reactnative.dev/docs/upgrading?os=macos".

Tested on a number of macOS and linux platforms, the behavior is the same. The difference is made by the Node version

Here is the output on an alpine-node23 docker:

System:
  OS: Linux 6.12 Alpine Linux
  CPU: (8) arm64 unknown
  Memory: 3.06 GB / 3.83 GB
  Shell:
    version: Unknown
    path: /bin/sh
Binaries:
  Node:
    version: 23.10.0
    path: /usr/local/bin/node
  Yarn:
    version: 1.22.22
    path: /usr/local/bin/yarn
  npm:
    version: 10.9.2
    path: /usr/local/bin/npm
  Watchman: Not Found
SDKs:
  Android SDK: Not Found
IDEs:
  Android Studio: Not Found
Languages:
  Java: Not Found
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.3.1
    wanted: ^18.3.1
  react-native:
    installed: 0.75.5
    wanted: ^0.77.*
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

info React Native v0.78.0 is now available (your project is running on v0.75.5).
info Changelog: https://github.com/facebook/react-native/releases/tag/v0.78.0
info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.75.5&to=0.78.0
info For more info, check out "https://reactnative.dev/docs/upgrading?os=linux".

Also tested with React Native versions between 0.75 and 0.77, they all exhibit the same behavior.

Stacktrace or Logs

vitest tests break with SyntaxError: Unexpected token 'typeof'

If the react vite plugin is removed, a more detailed error is shown

 FAIL  test/test.test.jsx [ test/test.test.jsx ]
RollupError: Parse failure: Expected 'from', got 'typeof'
At file: /Users/cristi/expo-vitest/node_modules/react-native/index.js:15:8
  File: /Users/cristi/expo-vitest/node_modules/react-native/index.js:15:8
  13 |  
  14 |  // APIs
  15 |  import typeof ActionSheetIOS from "/node_modules/react-native/Libraries/ActionSheetIOS/ActionSheetIOS.js";
     |         ^
  16 |  import typeof Alert from "/node_modules/react-native/Libraries/Alert/Alert.js";
  17 |  import typeof Animated from "/node_modules/react-native/Libraries/Animated/Animated.js";
 ❯ getRollupError node_modules/rollup/dist/es/shared/parseAst.js:397:41
 ❯ convertProgram node_modules/rollup/dist/es/shared/parseAst.js:1085:26
 ❯ parseAstAsync node_modules/rollup/dist/es/shared/parseAst.js:2071:106
 ❯ ssrTransformScript node_modules/vite/dist/node/chunks/dep-B0fRCRkQ.js:31239:11
 ❯ loadAndTransform node_modules/vite/dist/node/chunks/dep-B0fRCRkQ.js:41371:65

Node 22.7 displayed this more verbose error

(node:70023) [MODULE_TYPELESS_PACKAGE_JSON] Warning: file:///PATH/node_modules/react-native/index.js parsed as an ES module because module syntax was detected; to avoid the performance penalty of syntax detection, add "type": "module" to PATH/node_modules/react-native/package.json
(Use node --trace-warnings ... to show where the warning was created)

Reproducer

https://github.com/cristianbogdan/react-native-module-issue

Screenshots and Videos

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

先从 issue 中描述的 React Native 包元数据和 index.js 行为开始,然后在受影响的 Node 版本上使用 npm install 和 npm run test 运行链接的复现程序。将该结果与 npm run dev 以及所描述的 package.json 更改进行比较;当不使用 NODE_OPTIONS workaround 时测试套件不再失败,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, node.js, react-native
领域
mobile-dev, testing-qa
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。