You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 06:42:01