使用Expo构建的iOS应用闪屏后立即崩溃求助
Expo应用生产构建包模拟器崩溃排查方案
问题背景
使用Expo开发应用,通过EAS完成构建后,在Expo Go中运行正常,但在模拟器中启动生产构建包时会立即崩溃,目前已尝试查阅包文档、创建极简示例但未解决问题。
已尝试操作
- 查阅所有已安装包的官方文档,确认是否需要额外配置
- 创建极简示例,核心代码如下:
入口文件 index.tsx
// index.tsx import { SafeAreaView, Text } from "react-native"; export default function Index() { return ( <SafeAreaView> <Text className="text-blue">Sterk.</Text> </SafeAreaView> ); }
根布局 _layout.tsx
// _layout.tsx import { Stack } from "expo-router"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { BottomSheetModalProvider } from "@gorhom/bottom-sheet"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { useMigrations } from "drizzle-orm/expo-sqlite/migrator"; import { db, expodb } from "@/db"; import migrations from "@/drizzle/migrations"; import { useDrizzleStudio } from "expo-drizzle-studio-plugin"; import { useToast } from "@/hooks"; import { useEffect } from "react"; import { useColorScheme } from "react-native"; import { getHeaderStyle } from "@/utils"; export default function RootLayout() { const queryClient = new QueryClient(); const { showToast } = useToast(); const { error } = useMigrations(db, migrations); useEffect(() => { if (error) { showToast("Failed to migrate the database", "error"); console.log(error); } }, [error, showToast]); useDrizzleStudio(expodb); const colorScheme = useColorScheme(); return ( <QueryClientProvider client={queryClient}> <GestureHandlerRootView> <BottomSheetModalProvider> <Stack> <Stack.Screen name="index" options={{ headerShown: false }} /> <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> <Stack.Screen name="(onboarding)" options={{ headerShown: false }} /> <Stack.Screen name="welcome" options={{ headerShown: false }} /> <Stack.Screen name="paywall" options={{ headerShown: false, presentation: "fullScreenModal", }} /> <Stack.Screen name="(modals)/exercises/edit" options={{ ...getHeaderStyle(colorScheme), headerTitle: "Edit Exercise", headerLargeTitle: true, presentation: "fullScreenModal", }} /> <Stack.Screen name="(modals)/exercises/new" options={{ ...getHeaderStyle(colorScheme), headerTitle: "New Exercise", headerLargeTitle: true, presentation: "fullScreenModal", }} /> <Stack.Screen name="(modals)/legal/privacyPolicy" options={{ ...getHeaderStyle(colorScheme), headerTitle: "Privacy Policy", headerLargeTitle: true, presentation: "modal", }} /> <Stack.Screen name="(modals)/legal/termsOfService" options={{ ...getHeaderStyle(colorScheme), headerTitle: "Terms of Service", headerLargeTitle: true, presentation: "modal", }} /> </Stack> </BottomSheetModalProvider> </GestureHandlerRootView> </QueryClientProvider> ); }
文件夹布局

app.json 配置
{ "expo": { "name": "Sterk", "slug": "sterk", "version": "1.0.0", "userInterfaceStyle": "light", "orientation": "portrait", "scheme": "myapp", "icon": "./assets/app/icon.png", "ios": { "supportsTablet": false, "bundleIdentifier": <Left out on purpose> }, "android": { "adaptiveIcon": { "backgroundColor": "#ffffff" }, "package": <Left out on purpose> }, "web": { "bundler": "metro", "output": "static" }, "plugins": [ "expo-router", "expo-sqlite" ], "experiments": { "typedRoutes": true, "reactCompiler": true }, "newArchEnabled": true, "extra": { "router": { "origin": false }, "eas": { "projected": <Left out on purpose> } }, "owner": <Left out on purpose> } }
package.json 配置
{ "name": "sterk", "main": "expo-router/entry", "version": "1.0.0", "scripts": { "start": "expo start", "reset-project": "node ./scripts/reset-project.js", "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web", "test": "jest --watchAll", "lint": "expo lint" }, "jest": { "preset": "jest-expo" }, "dependencies": { "@gorhom/bottom-sheet": "^5.0.6", "@shopify/flash-list": "1.7.1", "@shopify/react-native-skia": "1.5.0", "@tanstack/react-query": "^5.51.11", "babel-plugin-inline-import": "^3.0.0", "babel-plugin-react-compiler": "^19.0.0-beta-a7bf2bd-20241110", "clsx": "^2.1.1", "drizzle-orm": "^0.37.0", "expo": "~52.0.20", "expo-dev-client": "^5.0.7", "expo-drizzle-studio-plugin": "0.1.0", "expo-haptics": "~14.0.0", "expo-linking": "~7.0.3", "expo-router": "~4.0.15", "expo-splash-screen": "~0.29.18", "expo-sqlite": "~15.0.4", "expo-symbols": "~0.2.0", "millify": "^6.1.0", "nativewind": "^2.0.11", "react": "18.3.1", "react-compiler-runtime": "^19.0.0-beta-0dec889-20241115", "react-native": "0.76.5", "react-native-gesture-handler": "~2.20.2", "react-native-reanimated": "~3.16.1", "react-native-safe-area-context": "4.12.0", "react-native-screens": "~4.4.0", "react-native-svg": "15.8.0", "react-native-web": "~0.19.13", "tailwindcss": "^3.3.2", "tailwind-merge": "^2.4.0", "zustand": "^4.5.4" }, "devDependencies": { "@babel/core": "^7.20.0", "@types/jest": "^29.5.12", "@types/react": "~18.3.12", "@types/react-test-renderer": "^18.0.7", "drizzle-kit": "^0.29.1", "eslint": "^8.57.0", "eslint-config-expo": "~8.0.1", "eslint-plugin-react-compiler": "^0.0.0-experimental-92aaa43-20240919", "expo-doctor": "^1.12.4", "jest": "^29.2.1", "jest-expo": "~52.0.2", "prettier": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.5", "react-test-renderer": "18.2.0", "typescript": "~5.3.3" }, "expo": { "doctor": { "reactNativeDirectoryCheck": { "listUnknownPackages": false } } }, "private": true }
metro.config.js 配置
const { getDefaultConfig } = require("@expo/metro-config"); const { wrapWithReanimatedMetroConfig, } = require('react-native-reanimated/metro-config'); const defaultConfig = getDefaultConfig(__dirname); defaultConfig.resolver.sourceExts.push("cjs"); defaultConfig.resolver.sourceExts.push('sql'); // <--- add this module.exports = wrapWithReanimatedMetroConfig(defaultConfig);
babel.config.js 配置
module.exports = function (api) { api.cache(true); return { presets: ["babel-preset-expo"], plugins: ["nativewind/babel", ["inline-import", { "extensions": [".sql"] }], 'react-native-reanimated/plugin'], }; };
排查与解决建议
- 提取崩溃堆栈日志:打开Xcode(iOS)或Android Studio(Android)的日志面板,筛选应用包名,找到崩溃时的详细堆栈信息,这是定位问题的核心依据。
- 禁用实验性特性:当前启用了
reactCompiler和newArchEnabled两个实验性特性,存在兼容性风险。先尝试关闭其中一个或全部,重新构建测试。 - 移除开发工具代码:生产构建中不需要
expo-drizzle-studio-plugin,在_layout.tsx中注释掉useDrizzleStudio(expodb),或通过环境变量条件渲染该代码,避免开发工具在生产环境引发错误。 - 验证SQLite迁移逻辑:
useMigrations在生产环境可能因权限或路径问题失败,尝试临时禁用自动迁移,或添加全局错误捕获,防止迁移失败导致应用崩溃。 - 检查第三方库兼容性:
@gorhom/bottom-sheet、@shopify/react-native-skia等库需适配新架构(若启用newArchEnabled),确认这些库是否支持新架构,或暂时关闭新架构测试。 - 清理构建缓存:执行
eas build --clear-cache后重新构建,避免缓存中的旧代码或配置干扰。 - 测试开发构建包:使用
eas build --profile development构建开发包,在模拟器中运行,开发包会保留调试日志,更容易捕获错误信息。 - 逐步排查依赖:创建仅包含核心依赖(expo、expo-router、react-native)的极简生产构建,确认正常运行后,逐个添加第三方依赖并测试,定位引发崩溃的具体依赖。
- 检查NativeWind配置:NativeWind v2在生产构建中可能需要额外配置,可尝试临时移除NativeWind及相关代码,验证是否因样式库导致崩溃。
- 确认环境变量完整性:检查生产构建中是否缺少必要的环境变量,如数据库配置等,导致初始化失败。
内容的提问来源于stack exchange,提问作者Thomas Rooskens
相关产品推荐
相关产品推荐

