React Native升级报错:无法解析react/index.js/jsx-runtime模块
升级React Native时模块解析路径异常问题
升级React Native后,持续遇到以下模块解析错误:路径被错误拼接为...node_modules/react/index.js/jsx-runtime,但正确路径应为...node_modules/react/jsx-runtime:
BUNDLE ./index.ts error: Error: Unable to resolve module monorepo/app/node_modules/react/index.js/jsx-runtime from monorepo/mobileChat/src/screens/index.tsx: None of these files exist: * node_modules/react/index.js/jsx-runtime(.native|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx) * node_modules/react/index.js/jsx-runtime/index(.native|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx) > 1 | import React from 'react' 2 | import { Navigation } from 'react-native-navigation' 3 | import { Provider } from 'react-redux' 4 | import getStore from 'shared/store' at ModuleResolver.resolveDependency (/Users/tbrownio/repos/bloom/bloomtext-frontend/mobileChat/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:152:15) at DependencyGraph.resolveDependency (/Users/tbrownio/repos/bloom/bloomtext-frontend/mobileChat/node_modules/metro/src/node-haste/DependencyGraph.js:264:43) at Object.resolve (/Users/tbrownio/repos/bloom/bloomtext-frontend/mobileChat/node_modules/metro/src/lib/transformHelpers.js:170:21) at resolveDependencies (/Users/tbrownio/repos/bloom/bloomtext-frontend/mobileChat/node_modules/metro/src/DeltaBundler/graphOperations.js:466:33) at processModule (/Users/tbrownio/repos/bloom/bloomtext-frontend/mobileChat/node_modules/metro/src/DeltaBundler/graphOperations.js:232:31) at async addDependency (/Users/tbrownio/repos/bloom/bloomtext-frontend/mobileChat/node_modules/metro/src/DeltaBundler/graphOperations.js:361:18) at async Promise.all (index 9) at async processModule (/Users/tbrownio/repos/bloom/bloomtext-frontend/mobileChat/node_modules/metro/src/DeltaBundler/graphOperations.js:279:3) at async addDependency (/Users/tbrownio/repos/bloom/bloomtext-frontend/mobileChat/node_modules/metro/src/DeltaBundler/graphOperations.js:361:18) at async Promise.all (index 3)
相关配置文件
package.json
{ "name": "mobileChat", "workspaces": { "nohoist": [ "jetifier", "react-native", "react-native/**", "@react-native-community/**", "react-native-navigation", "react-native-onesignal", "react-native-version-number", "react-native-image-crop-picker", "react-native-video", "react-native-keyboard-aware-scroll-view", "@sentry/**", "@amplitude/react-native", "react", "@testing-library/react-native", "@types/react-native" ] }, "version": "3.22.0", "private": true, "scripts": { "run-ios": "react-native run-ios", "run-android": "react-native run-android", "start": "node node_modules/react-native/local-cli/cli.js start", "ts": "tsc --noEmit --jsx react-native --project tsconfig.json", "ts:watch": "yarn ts --watch", "test": "yarn jest", "test:watch": "yarn jest --watch", "version": "react-native-version --never-increment-build" }, "dependencies": { "@amplitude/react-native": "2.16.1", "@babel/core": "^7.12.9", "@babel/plugin-transform-runtime": "7.13.9", "@babel/runtime": "7.12.5", "@react-native-async-storage/async-storage": "1.15.17", "@react-native-community/datetimepicker": "^3.5.2", "@react-native-community/netinfo": "4.7.0", "@react-native-community/push-notification-ios": "^1.10.0", "@react-native-community/toolbar-android": "^0.2.1", "@react-native-cookies/cookies": "6.0.11", "@sentry/react-native": "4.6.1", "@stream-io/flat-list-mvcp": "^0.10.1", "linkify-it": "3.0.3", "mdurl": "^1.0.1", "prop-types": "^15.7.2", "react": "18.1.0", "react-native": "0.70.6", "react-native-audio": "https://github.com/bloomapi/react-native-audio", "react-native-bidirectional-infinite-scroll": "^0.3.3", "react-native-deep-linking": "^2.2.0", "react-native-get-random-values": "^1.8.0", "react-native-image-crop-picker": "0.38.0", "react-native-iphone-x-helper": "1.3.1", "react-native-keyboard-aware-scroll-view": "0.9.5", "react-native-linear-gradient": "2.5.6", "react-native-navigation": "7.27.1", "react-native-onesignal": "4.3.3", "react-native-swipe-list-view": "^3.2.9", "react-native-version-number": "0.3.6", "react-native-video": "^6.0.0-alpha.3", "react-redux": "7.2.2", "redux": "4.0.5", "redux-logger": "3.0.6", "redux-persist": "4.10.2", "rn-fetch-blob": "0.12.0", "text-encoding-polyfill": "^0.6.7" }, "devDependencies": { "@babel/preset-env": "7.16.11", "@testing-library/jest-native": "^4.0.1", "@testing-library/react-hooks": "^7.0.1", "@testing-library/react-native": "^8.0.0", "@types/jest": "^26.0.23", "@types/react": "^18.0.21", "@types/react-native": "^0.70.6", "@types/react-test-renderer": "18.0.0", "babel-jest": "26.6.3", "babel-plugin-module-resolver": "4.1.0", "get-yarn-workspaces": "^1.0.2", "jest": "^26.6.3", "metro-react-native-babel-preset": "0.72.3", "react-native-version": "^4.0.0", "react-test-renderer": "18.1.0", "redux-devtools-extension": "^2.13.9", "typescript": "^4.8.3" } }
metro.config.js
/** * Metro configuration for React Native * https://github.com/facebook/react-native * * @format */ const path = require('path') const getWorkspaces = require('get-yarn-workspaces') const extraNodeModules = { 'mobile': path.resolve(__dirname, 'src'), 'components': 'mobile/components', 'screens': 'mobile/screens', } const workspaces = getWorkspaces(__dirname) const watchFolders = [ path.resolve(__dirname, '..', 'node_modules'), ...workspaces.filter(dir => dir !== __dirname), ] module.exports = { transformer: { getTransformOptions: async () => ({ transform: { experimentalImportSupport: false, inlineRequires: false, }, }), }, resolver: { extraNodeModules, }, watchFolders, }
babel.config.js
const path = require('path') module.exports = { "presets": ["module:metro-react-native-babel-preset"], "plugins": [ [ "module-resolver", { "extensions": [".ios.js", ".android.js", ".js", ".json"], "alias": { "react": require.resolve('react', { paths: [path.join(__dirname, './')] }), '^react-native$': require.resolve('react-native', { paths: [path.join(__dirname, './')] }), '^react-native/(.+)': ([, name]) => require.resolve(`react-native/${name}`, { paths: [path.join(__dirname, './')] }), }, }, ], ], }
问题原因与解决方案
问题根源
babel-plugin-module-resolver的配置中,将react的别名直接指向了react/index.js具体文件,而非react包的根目录。Metro解析react/jsx-runtime时,会将其视为相对于react/index.js的路径,从而错误拼接成react/index.js/jsx-runtime。
修复步骤
修改babel.config.js的react别名
将原来指向具体文件的配置,改为指向react包的根目录:// 替换原react别名配置 "react": path.resolve(__dirname, 'node_modules/react'),这样Metro解析
react/jsx-runtime时,会从react包根目录查找对应的模块。清除缓存并重新安装依赖
- 清除Metro缓存:
npx react-native start --reset-cache - 删除并重新安装依赖:
rm -rf node_modules && yarn install - 若为iOS项目,同步Pods:
cd ios && pod deintegrate && pod install && cd ..
- 清除Metro缓存:
验证配置
重启Metro服务,重新打包项目,确认模块解析错误是否消失。
内容的提问来源于stack exchange,提问作者Tyler Brown
相关产品推荐
相关产品推荐

