react / react/react-native

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

Open
#50,052 17 comments 10 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Needs: Attention Needs: Version Info
Dominant language
C++
Stars
127k
Forks
25.3k
Avg merge
1d 23h
Merged PRs (30d)
4

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the React Native package metadata and index.js behavior described in the issue, then run the linked reproducer with npm install and npm run test on an affected Node version. Compare that result with npm run dev and with the package.json change described; done means the test suite no longer fails without the NODE_OPTIONS workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js, react-native
Domain
mobile-dev, testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.