should explicitly declare type:commonjs since Node experimental-detect-module is on by default
まだ誰も着手していません。
- 主要言語
- C++
- スター
- 127k
- フォーク
- 25.3k
- 平均マージ
- 1日 23時間
- マージ済み PR(30日)
- 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
- checkout the reproduction repo, run
npm install - switch to a recent node version like 20.19 or later, 22.7 or later, 23
npm run test(which executes vitest) will fail withSyntaxError: 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 expoworks for any Node version supported by React Native.- edit
node_modules/react-native/package.jsonand add"type":"commonjs". This will helpnpm run testwork 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
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
issue に記載されている React Native パッケージのメタデータと index.js の動作から始め、影響を受ける Node バージョンで npm install と npm run test を使ってリンク先の再現コードを実行します。その結果を npm run dev および説明されている package.json の変更と比較します。NODE_OPTIONS の回避策なしでテストスイートが失敗しなくなれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- javascript, node.js, react-native
- 領域
- mobile-dev, testing-qa
- issue の種類
- バグ
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 45/100