使用 EAS Build 时排除构建错误和崩溃的参考。
当出现问题时,可能会以以下两种方式之一出现问题:
¥When something goes wrong, it probably will go wrong in one of two following ways:
你的构建将会失败。
¥Your build will fail.
构建将成功,但会遇到运行时错误,例如,运行时崩溃或挂起。
¥The build will succeed but encounter a runtime error, for example, it crashes or hangs when you run it.
关于 缩小错误来源范围 的所有标准建议均适用于此处;本文档提供的信息可能对你的典型故障排除过程和技术有用。故障排除是一门艺术,你可能需要创造性地思考。
¥All standard advice around narrowing down the source of an error applies here; this document provides information that may be useful on top of your typical troubleshooting processes and techniques. Troubleshooting is an art, and you might need to think creatively.
¥Find the related error logs
在进一步操作之前,你需要确保已找到错误消息并阅读它。根据你是调查构建失败还是运行时错误,执行此操作的方式会有所不同。
¥Before you go further, you need to be sure that you have located the error message and read it. How you do this will be different depending on whether you're investigating a build failure or runtime error.
¥Runtime errors
属于此类别的常见问题有:"我的应用在本地运行良好,但当我运行构建时立即崩溃" 或 "我的应用可以在 Expo Go 中运行,但在我的构建中挂在启动屏幕上"。当你的应用构建成功但在运行时崩溃或挂起时,这被视为运行时错误。
¥Common questions that fall under this category are: "my app runs well locally but crashes immediately when I run a build" or "my app works in Expo Go but hangs on the splash screen in my build". When your app builds successfully but crashes or hangs when you run it, this is considered a runtime error.
请参阅 调试指南 "生产错误" 部分 了解如何在发布版本在运行时崩溃时查找日志。
¥Refer to the "Production errors" section of the debugging guide to learn how to locate logs when your release builds are crashing at runtime.
如果你无法通过这种方法找到任何有用的信息,请尝试 逐步缩小崩溃根源。
¥If you can't find any useful information through this approach, try narrowing down the source of the crash step by step.
¥Build errors
转到构建详细信息页面(如果尚未打开,请在 构建仪表板 上找到它)并通过单击任何失败的构建阶段来展开它们。通常,最早出现错误的阶段将包含最有用的信息,并且任何后续失败的阶段都将从第一个阶段开始级联。
¥Go to your build details page (find it on the build dashboard if you don't have it open already) and expand any failed build phases by clicking on them. Often, the earliest phase with errors will contain the most useful information and any subsequent failed phase will have cascaded from the first.
无论处于哪个阶段,都经常会看到以 [stderr]
为前缀的日志条目,但请记住,这并不一定意味着这些日志指向错误;CLI 工具通常使用 stderr 来输出警告和其他诊断信息。
¥Regardless of the phase, it's common to see log entries prefixed with [stderr]
, but keep in mind that this doesn't necessarily mean those logs point to errors; it's common for CLI tools to use stderr to output warnings and other diagnostics.
例如,你可能会在 Android 版本上看到类似的内容:
¥For example, you might see something like this on your Android builds:
[stderr] Note: /build/workingdir/build/app/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java uses or overrides a deprecated API.
[stderr] Note: Recompile with -Xlint:deprecation for details.
尽管你可能有兴趣跟进该警告,也可能不感兴趣,但这并不是构建失败的原因。那么你如何知道哪些日志真正负责呢?如果你正在构建一个裸项目,那么你已经擅长于此。如果你正在构建 管理项目,这可能会很棘手,因为你不直接与原生代码交互,只编写 JavaScript。
¥While you may or may not be interested in following up on that warning, it is not the cause of your failed build. So how do you know which logs are truly responsible? If you are building a bare project, you will already be good at this. If you are building a managed project, it may be tricky because you don't directly interact with the native code, only write JavaScript.
一个好的方法是确定构建是否由于原生错误或 JavaScript 错误而失败。当你的构建由于 JavaScript 构建错误而失败时,你通常会看到如下内容:
¥A good path forward is to determine if the build failed due to a native or JavaScript error. When your build fails due to a JavaScript build error, you will usually see something like this:
❌ Metro encountered an error:
Unable to resolve module ./src/Routes from /Users/expo/workingdir/build/App.js
此特定错误意味着应用正在导入 ./src/Routes 但未找到。原因可能是 Git 中的文件名大小写与开发者的文件系统不同(例如,Git 中的 paths.js 而不是 Routes.js),或者项目可能有一个构建步骤,但未设置为在其上运行 EAS 构建。在这种情况下,事实证明,在这种情况下 ./src/Routes 旨在导入 ./src/Routes/index.js,但该路径被意外地排除在开发者的 .gitignore 中。
¥This particular error means that the app is importing ./src/Routes and it is not found. The cause could be that the filename case is different in Git than the developer's filesystem (for example, routes.js in Git instead of Routes.js), or maybe the project has a build step and it wasn't set up to run on EAS Build. In this case, it turns out that in this case ./src/Routes was intended to import ./src/Routes/index.js, but that path was accidentally excluded in the developer's .gitignore.
需要注意的是,对于 iOS 构建,构建详细信息页面仅显示日志的缩略版本,因为 xcodebuild
的完整输出可能约为 10MB。有时需要打开完整的 Xcode 日志来查找所需的信息;例如,如果 JavaScript 构建失败,但你在构建详细信息页面上看不到任何有用的信息。要打开完整的 Xcode 日志,请在构建完成后滚动到构建详细信息页面的底部,然后单击查看或下载它们。
¥It's important to note that with iOS builds the build details page only displays an abridged version of the logs because the full output from xcodebuild
can be in the order of 10MB. Sometimes it's necessary to open the full Xcode logs to find the information that you need; for example, if the JavaScript build failed but you don't see any useful information on the build details page. To open the full Xcode logs, scroll to the bottom of the build details page when the build has been completed and either click to view or download them.
如果你正在开发托管应用,并且构建错误是原生错误而不是 JavaScript 错误,则这可能是由于项目中的 配置插件 或依赖造成的。请留意日志中自上次成功构建以来添加的任何新软件包。运行 npx expo-doctor
以确定你的项目中的 Expo SDK 依赖的版本与你的 Expo SDK 版本兼容。
¥If you are working on a managed app and the build error is a native error rather than a JavaScript error, this is likely due to a config plugin or a dependency in your project. Keep an eye out in the logs for any new packages that you have added since your previous successful build. Run npx expo-doctor
to determine that the versions of Expo SDK dependencies in your project are compatible with your Expo SDK version.
有了错误日志,你通常可以开始修复构建或搜索 forums 和 GitHub 问题以查找相关包以进行更深入的挖掘。下面列出了一些常见的问题来源。
¥Armed with your error logs, you can often start to fix your build or search the forums and GitHub issues for related packages to dig deeper. Some common sources of problems are listed below.
Monorepos 非常有用,但它们确实引入了自己的一系列问题。需要将整个 monorepo 上传到 EAS Build 构建器、进行设置并运行构建。
¥Monorepos are incredibly useful but they do introduce their own set of problems. It's necessary to upload the entire monorepo to the EAS Build builders, set it up, and run the build.
EAS Build 更像是一个典型的 CI 服务,因为我们需要源代码,而不是编译后的 JavaScript 包和清单。EAS Build 对 Yarn 工作区和 使用其他 monorepo 工具时,你的成功可能会有所不同 具有一流的支持。
¥EAS Build is more like a typical CI service in that we need the source code, rather than a compiled JavaScript bundle and manifest. EAS Build has first-class support for Yarn workspaces, and your success may vary when using other monorepo tools.
欲了解更多信息,请参阅 使用单一存储库。
¥For more information, see Working with monorepos.
如果你的构建失败并在 Gradle 日志中显示 "Gradle 构建守护进程意外消失(它可能已被杀死或可能已崩溃)",这可能是因为负责打包应用 JavaScript 的 Node 进程已被终止。
¥If your build fails with "Gradle build daemon disappeared unexpectedly (it may have been killed or may have crashed)" in your Gradle logs, this may be because the Node process responsible for bundling your app JavaScript was killed.
这通常表明你的应用包非常大,这将使你的整个应用二进制文件更大并导致启动时间变慢,尤其是在低端 Android 设备上。有时,当将大型文本文件视为源代码时,可能会出现此错误,例如,如果你有一个 JavaScript 文件,其中包含要加载到 Web 视图中的 1MB 以上 HTML 字符串,或类似大小的 JSON 文件。
¥This can often be a sign that your app bundle is extremely large, which will make your overall app binary larger and lead to slow boot up times, especially on low-end Android devices. Sometimes the error can occur when large text files are treated as source code, for example, if you have a JavaScript file that contains a string of 1MB+ of HTML to load into a webview, or a similarly sized JSON file.
要确定你的包有多大并查看大小来源的详细信息,请使用 react-native-bundle-visualizer。
¥To determine how large your bundle is and to see a breakdown of where the size comes from, use react-native-bundle-visualizer.
要增加 EAS Build 构建器的内存限制,你可以在 eas.json 中使用 large
资源类。有关详细信息,请参阅 Android 特定的资源类 和 iOS 特定的资源类。
¥To increase memory limits on your EAS Build builders, you can use large
resource class in your eas.json. See Android-specific resource class and iOS-specific resource class for more information.
当你运行 eas build
时,你的项目文件将上传到 Expo 的构建服务器。但是,.gitignore 中提到的任何文件或目录都不会上传。这是为了防止敏感信息(例如 API 密钥)暴露在应用代码中。
¥When you run eas build
, your project's files are uploaded to Expo's build servers. However, any file or directory mentioned in the .gitignore is not uploaded. This is intentional to prevent sensitive information, such as API keys, from being exposed in your app's code.
如果你的项目导入 .gitignore 中列出的文件,则构建将失败并出现 None of these files exist
错误。有多种方法可以解决此错误:
¥If your project imports a file listed in .gitignore, the build will fail with a None of these files exist
error. There are different ways you can resolve this error:
删除被忽略文件的导入语句并测试你的项目。如果你的项目按预期运行,则该导入语句可能已过时或未使用。
¥Remove the import statement for the ignored file and test your project. If your project functions as expected, that import statement may have been outdated or unused.
删除 Metro 无法从 .gitignore 解析的所有文件或目录。但是,这会带来安全风险,因为这些文件中包含的任何敏感信息现在都可以在项目的源代码和 Git 提交历史记录中找到。
¥Remove any files or directories Metro was unable to resolve from your .gitignore. However, this poses a security risk since any sensitive information included in these files will now be available in your project's source code and Git commit history.
使用 base64
对文件进行编码,将该字符串保存为密钥,然后在 EAS 构建钩子中创建该文件。请参阅 如果文件被 gitignored,我如何将它们上传到 EAS Build? 了解更多信息。
¥Encode the file with base64
, save that string as secrets, and create the file in an EAS Build hook. See How can I upload files to EAS Build if they are gitignored? for more information.
重构源代码以避免在客户端导入敏感文件。如果文件是第三方提供商自动生成的代码,并且该提供商已自动在你的 .gitignore 中列出文件,则该文件可能包含敏感信息。你不应该将其包含在客户端。在应用开发过程中,请确保遵循安全实践,例如使用环境变量或通过后端提供服务。请参阅 在环境变量中使用秘密 了解更多信息。
¥Refactor your source code to avoid importing sensitive files on the client side. If a file is an auto-generated code from a third-party provider and that provider has automatically listed files in your .gitignore, then that file probably contains sensitive information. You should not include it on the client side. During app development, ensure you follow secure practices, such as using environment variables or serving them through your backend. See Using secrets in environment variables for more information.
¥Verify that your JavaScript bundles locally
当构建因 Task :app:bundleReleaseJsAndAssets FAILED
(Android) 或 Metro encountered an error
(iOS) 失败时,这意味着 Metro 打包程序在尝试将应用的 JavaScript 代码嵌入到应用的二进制文件中时无法打包该代码。此错误消息后通常会出现语法错误或有关打包失败原因的其他详细信息。不幸的是,标准的 React Native 项目被配置为在 Gradle/Xcode 构建步骤的后期执行此步骤,这意味着可能需要一段时间才能看到此错误。
¥When a build fails with Task :app:bundleReleaseJsAndAssets FAILED
(Android) or Metro encountered an error
(iOS), it means Metro bundler was unable to bundle the app's JavaScript code while trying to embed it in your app's binary. This error message is usually followed by a syntax error or other details about why bundling failed. Unfortunately, a standard React Native project is configured to perform this step late in the Gradle/Xcode build step, meaning it can take a while to see this error.
你可以通过运行 npx expo export
在本地构建生产包,以绕过所有其他构建步骤,这样你就可以更快地看到此错误。重复运行此命令,解决任何语法错误或其他发现的问题,直到打包包成功构建。然后再次尝试你的 EAS 构建。
¥You can build the production bundle locally by running npx expo export
to bypass all of the other build steps so you can see this error much more quickly. Run this command repeatedly, resolving any syntax errors or other issues uncovered until the bundle builds successfully. Then try your EAS Build again.
¥Verify that your project builds and runs locally
如果日志不足以立即帮助你了解并修复根本原因,那么是时候尝试在本地重现问题了。如果你的项目在发布模式下在本地构建并运行,那么它也将在 EAS Build 上构建,前提是满足以下条件:
¥If the logs weren't enough to immediately help you understand and fix the root cause, it's time to try to reproduce the issue locally. If your project builds and runs locally in release mode then it will also build on EAS Build, provided that the following are all true:
相关 构建工具版本(例如 Xcode、Node.js、npm、Yarn)在两种环境中都是相同的。
¥Relevant Build tool versions (for example, Xcode, Node.js, npm, Yarn) are the same in both environments.
相关 环境变量 在两种环境中都是相同的。
¥Relevant environment variables are the same in both environments.
上传到 EAS Build 的 archive 包含相同的相关源文件。
¥The archive that is uploaded to EAS Build includes the same relevant source files.
你可以使用 npx expo run:android
和 npx expo run:ios
命令验证你的项目是否在本地计算机上构建,并将变体/配置标志设置为发布,以最忠实地重现 EAS Build 上执行的内容。有关详细信息,请参阅 安卓构建流程 和 iOS 构建过程。
¥You can verify that your project builds on your local machine with the npx expo run:android
and npx expo run:ios
commands, with variant/configuration flags set to release to most faithfully reproduce what executes on EAS Build. For more information, see Android build process and iOS build process.
# Locally compile and run the Android app in release mode
-
npx expo run:android --variant release
# Locally compile and run the iOS app in release mode
-
npx expo run:ios --configuration Release
如果使用 CNG,这些命令将运行
npx expo prebuild
来生成原生项目来编译它们。完成故障排除后,你可能需要 清理更改,除非你想直接开始管理这些项目而不是按需生成它们。¥If use CNG, these commands will run
npx expo prebuild
to generate native projects to compile them.You likely want to clean up the changes once you are done troubleshooting, unless you want to start managing these projects directly instead of generating them on demand.
你也可以使用
eas build --local
运行本地构建 - 该命令将运行一系列与托管 EAS 构建服务上远程运行的步骤尽可能接近的步骤。它将你的项目复制到临时目录并在那里进行任何必要的更改。了解如何设置它并使用它进行调试。¥You can alternatively run a local build with
eas build --local
— this command will run a series of steps that is as close as it can be to what runs remotely on the hosted EAS Build service. It will copy your project to a temporary directory and make any necessary changes there. Learn how to set this up and use it for debugging.
如果你的原生工具链已正确安装,并且你无法在本地计算机上以发布模式构建和运行项目,则它将无法在 EAS Build 上构建。在本地修复问题,然后在 EAS Build 上重试。本文档中的其他建议可能有助于帮助你在本地解决问题,但这通常需要一些原生工具知识或明智地应用 Google、Stack Overflow 和 GitHub 问题。
¥If your native toolchains are installed correctly and you are unable to build and run your project in release mode on your local machine, it will not build on EAS Build. Fix the issues locally, then try again on EAS Build. The other advice in this doc may be useful to help you resolve the issue locally, but often this requires some knowledge of native tooling or judicious application of Google, Stack Overflow, and GitHub Issues.
如果你没有在本地安装原生工具链,例如,因为你没有 Apple 计算机,因此无法在你的计算机上构建 iOS 应用,则要找出构建错误的根源可能会更加棘手。在本地进行小更改然后在 EAS Build 上查看结果的反馈循环比在本地执行相同步骤要慢,因为 EAS Build 构建器必须在开始构建之前设置其环境、下载项目并安装依赖。
¥If you do not have native toolchains installed locally, for example, because you do not have an Apple computer and therefore cannot build an iOS app on your machine, it can be trickier to get to the bottom of build errors. The feedback loop of making small changes locally and then seeing the result on EAS Build is slower than doing the same steps locally because the EAS Build builder must set up its environment, download your project, and install dependencies before starting the build.
如果你愿意并且能够设置适当的原生工具,请参阅 React Native 环境搭建指南。
¥If you are willing and able to set up the appropriate native tools, then refer to the React Native environment setup guide.
默认情况下,EAS Build 遵循相对简单的流程来构建应用(安卓 或 iOS 系统)。如果 npx expo run:android --variant release
和 npx expo run:ios --configuration Release
在本地工作,但你的构建失败,那么是时候缩小你的计算机上存在哪些配置尚未在 EAS Build 上为你的项目设置的范围了。
¥By default, EAS Build follows a relatively straightforward process for building your app for (Android or iOS). If npx expo run:android --variant release
and npx expo run:ios --configuration Release
work locally, but your builds fail, then it's time to narrow down what configuration exists on your machine that hasn't been set up for your project on EAS Build yet.
将项目的新 git clone
复制到新目录并使其运行,最好是在不同的计算机上运行。请注意所需的每个步骤,并验证它们是否也针对 EAS 构建进行了配置。
¥Do a fresh git clone
of your project to a new directory and get it running, ideally on a different machine. Pay attention to each of the steps that are needed and verify that they are also configured for EAS Build.
检查你的 环境变量 是否配置正确。
¥Check that your environment variables are properly configured.
验证 Node.js、npm、Yarn、Xcode、Java 和其他工具的版本在两个环境中是否相同。
¥Verify that versions of Node.js, npm, Yarn, Xcode, Java, and other tools are the same in both environments.
确保 你正在上传到 EAS Build 的存档 包含相同的相关源文件。
¥Ensure that the archive you are uploading to EAS Build includes the same relevant source files.
你可以通过使用 npx expo start --no-dev
启动应用来测试应用的 JS 部分如何在生产环境中运行。这告诉打包器在提供 JavaScript 之前缩小 JavaScript,最明显的是剥离受 __DEV__
布尔值保护的代码。这将删除大部分日志记录、HMR、快速刷新功能,并使调试变得更加困难,但你可以通过这种方式更快地迭代生产包。
¥You can test how the JS part of your app will run in production by starting it with npx expo start --no-dev
. This tells the bundler to minify JavaScript before serving it, most notably stripping code protected by the __DEV__
boolean. This will remove most of the logging, HMR, Fast Refresh functionality, and make debugging a bit harder, but you can iterate on the production bundle faster this way.
¥Still having trouble?
本指南远非全面,并且根据你的经验水平,你可能仍然难以让你的应用正常运行。
¥This guide is far from being comprehensive, and depending on your level of experience you might still be struggling to get your app working.
如果你遵循了此处的建议,那么你现在就可以向其他开发者描述你的问题并获得一些帮助。
¥If you have followed the advice here, you're now in a good position to describe your issue to other developers and get some help.
¥How to ask a good question
在 Discord and Forums 加入我们,向社区和 Expo 团队寻求帮助。Expo 团队会尽最大努力回应高质量且清晰明确的问题,但除非你注册了 支持计划,否则不能保证得到回应。为确保 Expo 团队成员看到你的问题,你可以在 expo.dev/contact 提交票证。
¥Join us on Discord and Forums to ask for help from the community and the Expo team. The Expo team does our best to respond to high quality and well-articulated questions and issues, but responses are not guaranteed unless you are signed up for a support plan. To ensure that an Expo team member sees your question, you can file a ticket at expo.dev/contact.
当你寻求故障排除帮助时,请务必分享以下信息:
¥When you ask for troubleshooting help, be sure to share the following information:
指向你的构建页面的链接。只有你的团队或 Expo 员工才能访问此内容。如果你想更公开地分享,请截取屏幕截图。如果你想更私密地分享,请发送电子邮件至 secure@expo.dev,并在聊天或论坛上的帮助请求中提及这一点。如果你使用 eas build --local
在本地执行此构建,则可以省略此内容,但请指出这一事实。
¥A link to your build page. This can only be accessed by your team or Expo employees. If you'd like to share it more publicly, take a screenshot. If you'd like to share it more privately, send an email to secure@expo.dev and mention that in your help request on chat or forums. If you are performing this build locally with eas build --local
, you may omit this, but please indicate this fact.
错误日志。你怀疑的任何事情都可能与你的构建或运行时错误有关。如果你无法提供此信息,请解释原因。
¥Error logs. Anything that you suspect may be related to your build or runtime error. If you can't provide this, please explain why not.
最小的可重现示例或存储库的链接。解决问题的最快方法是确保其他开发者可以重现该问题。如果你曾经在团队中工作过,你就会从经验中知道这一点。在许多情况下,如果你无法提供可重现的示例,那么它可能无法为你提供帮助,并且来回询问和回答问题的过程充其量只是一种低效的时间利用。在 手动调试指南 和 Stack Overflow 的 最小可行可重复示例 指南中了解有关如何创建可重现示例的更多信息。
¥Minimal reproducible example or a link to your repository. The quickest way to get a solution to your problem is to ensure that other developers can reproduce it. If you have ever worked on a team, you know this from experience. In many cases, if you can't provide a reproducible example then it may not be possible to help you, and at best the back-and-forth process of asking and answering questions will be an inefficient use of time. Learn more about how to create a reproducible example in the manual debugging guide and Stack Overflow's Minimal Viable Reproducible Example guide.
尽量做到清晰、准确且有帮助。Stack Overflow 的 如何提出一个好问题 指南提供的一般指导适用。
¥Try to be clear, precise, and helpful. General guidance provided by Stack Overflow's How to ask a good question guide applies.