构建React Native+Expo项目APK时AppEntry.js模块解析失败求助
node_modules/expo/AppEntry.js 我在为React Native项目构建APK时,每次执行到createBundleAmazonReleaseJsAndAssets任务都会报错:
Error: Unable to resolve module .\node_modules\expo\AppEntry.js from C:\Users\tosey\GlaucaAI/.: .\node_modules\expo\AppEntry.js could not be found within the project or in these directories:
node_modules
..\node_modules
at ModuleResolver.resolveDependency (C:\Users\tosey\GlaucaAI\node_modules\metro\src\node-haste\DependencyGraph\ModuleResolution.js:138:15)
我尝试过删除node_modules重新执行yarn安装,也安装了metro-react-native-babel-transformer,但都没用。附上我的package.json:
{ "name": "GlaucaAI", "version": "0.8.0", "main": "node_modules/expo/AppEntry.js", "scripts": { "writeAssetsBundle": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res", "buildAppAPK": "cd android && ./gradlew clean && ./gradlew assembleRelease --warning-mode=all --stacktrace --scan --info", "buildAppAAB": "cd android && ./gradlew clean && ./gradlew bundleRelease --warning-mode=all --stacktrace --scan --info", "dependencyConflict": "cd android && ./gradlew app:dependencyInsight --configuration amazonReleaseRuntimeClasspath --dependency your-dependency-name", "start": "npx expo start", "begin": "npm exec expo start", "dev:build:ios": "eas build --profile development --platform ios", "dev:build:android": "eas build --profile development --platform android", "test": "jest", "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web" }, "dependencies": { "@babel/preset-env": "^7.24.7", "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@expo/vector-icons": "^14.0.0", "@expo/webpack-config": "~19.0.1", "@google/generative-ai": "^0.1.2", "@pubnub/react-native-chat-components": "0.27.0", "@react-native-async-storage/async-storage": "1.23.1", "@react-native-masked-view/masked-view": "^0.3.1", "@react-native-picker/picker": "2.7.5", "@react-native/metro-config": "^0.74.84", "@react-navigation/bottom-tabs": "^6.5.8", "@react-navigation/material-top-tabs": "^6.6.3", "@react-navigation/native": "^6.1.7", "@react-navigation/stack": "^6.3.17", "@stripe/stripe-react-native": "0.37.2", "axios": "^1.4.0", "babel-preset-expo": "^11.0.8", "deepai": "^1.0.23", "expo": "^51.0.12", "expo-av": "~14.0.5", "expo-build-properties": "~0.12.3", "expo-constants": "~16.0.2", "expo-device": "~6.0.2", "expo-document-picker": "~12.0.1", "expo-file-system": "~17.0.1", "expo-font": "~12.0.7", "expo-image-picker": "~15.0.5", "expo-in-app-purchases": "~14.3.0", "expo-linking": "~6.3.1", "expo-local-authentication": "~14.0.1", "expo-notifications": "~0.28.7", "expo-permissions": "~14.2.1", "expo-print": "~13.0.1", "expo-sharing": "~12.0.1", "expo-splash-screen": "~0.27.5", "expo-sqlite": "~14.0.3", "expo-status-bar": "~1.12.1", "expo-tracking-transparency": "~4.0.2", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.74.2", "react-native-elements": "^3.4.3", "react-native-gesture-handler": "~2.16.1", "react-native-iap": "12.13.0", "react-native-image-zoom-viewer": "^3.0.1", "react-native-joyride": "^1.0.1", "react-native-keychain": "^8.1.2", "react-native-marquee-ab": "^1.2.6", "react-native-pager-view": "6.3.0", "react-native-paper": "^5.11.3", "react-native-pdf": "^6.7.1", "react-native-reanimated": "^3.12.0", "react-native-safe-area-context": "4.10.1", "react-native-screens": "3.31.1", "react-native-secure-key-store": "^2.0.10", "react-native-sqlite-storage": "^6.0.1", "react-native-swiper": "^1.6.0", "react-native-tab-view": "^3.5.2", "react-native-vector-icons": "^10.1.0", "react-native-web": "~0.19.10", "react-native-webview": "13.8.6", "rn-sliding-up-panel": "^2.4.6", "text-encoding": "^0.7.0", "yarn": "^1.22.22" }, "devDependencies": { "@babel/core": "^7.24.7", "@babel/plugin-transform-class-properties": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "babel-plugin-module-resolver": "^5.0.2", "@types/jest": "25.2.3", "@types/react": "~18.2.45", "@types/react-test-renderer": "17.0.1", "babel-jest": "27.0.6", "eslint": "7.32.0", "jest": "^29.4.0", "metro": "^0.80.9", "metro-config": "^0.80.9", "metro-react-native-babel-preset": "^0.77.0", "metro-react-native-babel-transformer": "^0.77.0", "typescript": "^5.1.3" }, "private": true }
解决步骤
1. 修正package.json的main字段
Expo的node_modules/expo/AppEntry.js仅在Expo官方构建流程中生效,直接用gradlew构建时需要指向你项目自己的入口文件。修改main字段为项目实际入口:
"main": "index.js"
如果你的项目入口是App.js,就改成"main": "App.js"。
2. 统一入口文件配置
你的writeAssetsBundle脚本指定的入口是index.js,但package.json的main之前指向Expo的入口,两者不一致会导致Metro解析混乱。确保脚本的--entry-file参数和package.json的main字段指向同一个文件。
3. 移除冲突依赖
- 同时存在
expo-sqlite和react-native-sqlite-storage,这两个都是SQLite库,会导致冲突,删除其中一个:yarn remove react-native-sqlite-storage expo-permissions在Expo 44+已被废弃,所有权限请求都集成到对应功能模块(比如expo-image-picker自己处理权限),删除该依赖:yarn remove expo-permissions
4. 重置Metro配置
在项目根目录创建或修改metro.config.js,使用React Native官方默认配置,排除自定义配置的问题:
const { getDefaultConfig } = require('@react-native/metro-config'); const config = getDefaultConfig(__dirname); module.exports = config;
5. 适配Expo构建流程
如果是Expo项目,优先使用Expo官方构建命令,避免原生环境不兼容:
eas build --platform android --profile production
如果一定要用gradlew构建,先执行expo prebuild生成适配的原生项目文件,再进行构建:
expo prebuild --platform android cd android && ./gradlew assembleRelease
6. 彻底清理缓存并重装依赖
执行以下命令清空所有缓存和旧构建文件:
yarn cache clean rm -rf node_modules rm package-lock.json yarn.lock rm -rf android/.gradle android/build android/app/build rm -rf .expo yarn install
内容的提问来源于stack exchange,提问作者Tosin Seyi

