# Expo SDK Documentation > Documentation for Expo SDK libraries, app configuration files, Expo CLI, create-expo-app, and more. --- title: create-expo-app description: 一个命令行工具,用于创建新的 Expo 和 React Native 项目。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/more/create-expo/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # create-expo-app 一个命令行工具,用于创建新的 Expo 和 React Native 项目。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. `create-expo-app` 是一个命令行工具,用于创建和设置一个新的 Expo 和 React Native 项目。该工具通过提供多种模板来简化初始化流程,使你无需手动配置即可快速开始。 ## 创建新项目 要创建新项目,请运行以下命令: ```sh # npm npx create-expo-app@latest --template default@sdk-55 # yarn yarn create expo-app --template default@sdk-55 # pnpm pnpm create expo-app --template default@sdk-55 # bun bun create expo --template default@sdk-55 ``` > **注意:** 在 SDK 55 过渡期内,不带 `--template` 标志的 `create-expo-app@latest` 会创建一个 SDK 54 项目。如果你计划在实体设备上使用 Expo Go,请使用 SDK 54 项目。否则,请使用 `--template default@sdk-55` 来创建 SDK 55 项目。 运行上述命令后,系统会提示你输入项目的应用名称。这个应用名称也会用于 app config 的 [`name`](/versions/latest/config/app#name) 属性。 ```sh 你的应用名称是什么? my-app ``` ## 选项 使用以下选项来自定义命令行为。 ### `--yes` 使用默认选项创建新项目。 ### `--no-install` 跳过安装 npm 依赖或 CocoaPods。 ### `--no-agents-md` 跳过生成 **AGENTS.md**、**CLAUDE.md** 和 **.claude/settings.json**。默认情况下,`create-expo-app` 会生成这些文件,以便 AI 编码代理(例如 Claude Code)能够自动获得 Expo 特定上下文并配置 [`expo` skills 插件](https://expo.dev/expo-skills)。生成的 **AGENTS.md** 会指向与你项目 SDK 版本匹配的分版本 Expo 文档。 ### `--template` 使用 [Node Package Manager](/more/create-expo#node-package-managers-support) 运行 `create-expo-app` 会使用默认模板初始化并设置一个新的 Expo 项目。 你可以使用 `--template` 选项选择以下模板之一,也可以将其作为该选项的参数传入。例如,`--template default`。 > **信息** 想要更多模板吗?请查看 [`--example`](/more/create-expo#--example) 选项,以使用展示特定功能和集成的示例应用之一来初始化你的项目。 | 模板 | 描述 | | --- | --- | | [`default`](https://github.com/expo/expo/tree/main/templates/expo-template-default) | 默认模板。专为构建多页面应用而设计。包含推荐工具,如 Expo CLI、已启用的 Expo Router 库和 TypeScript 配置。适用于大多数应用。 | | [`blank`](https://github.com/expo/expo/tree/main/templates/expo-template-blank) | 安装最低必需的 npm 依赖,但不配置导航。 | | [`blank-typescript`](https://github.com/expo/expo/tree/main/templates/expo-template-blank-typescript) | 启用 TypeScript 的空白模板。 | | [`tabs`](https://github.com/expo/expo/tree/main/templates/expo-template-tabs) | 安装并配置基于文件的路由,启用 Expo Router 和 TypeScript。 | | [`bare-minimum`](https://github.com/expo/expo/tree/main/templates/expo-template-bare-minimum) | 一个生成了原生目录(**android** 和 **ios**)的空白模板。会在设置过程中运行 [`npx expo prebuild`](/workflow/continuous-native-generation)。 | ### `--example` 使用此选项可以通过 [expo/examples](https://github.com/expo/examples) 中的示例来初始化项目。 例如: - 运行 `npx create-expo-app --example with-router` 会设置一个使用 Expo Router 库的项目 - 运行 `npx create-expo-app --example with-react-navigation` 会设置一个类似默认模板的项目,但配置为使用原生的 React Navigation 库 ### `--version` 打印版本号并退出。 ### `--help` 打印可用选项列表并退出。 ## Node Package Managers 支持 使用 `create-expo-app` 创建新项目时,也会处理为特定 Node Package Manager 所需的额外配置。 **如果你正在从一个包管理器迁移到另一个包管理器**,你需要在项目中手动完成额外配置。**如果你正在使用 [EAS](/eas)**,你也需要手动为任何额外必需步骤配置项目。 每种包管理器的所有额外步骤如下所列。 ### npm #### 本地安装 npm 是作为 Node.js 安装的一部分提供的。安装说明请参见 [Node.js 文档](https://nodejs.org/en/download/package-manager)。 #### EAS 安装 如果项目目录包含 **package-lock.json**,则默认支持。 ### Yarn 1 (Classic) #### 本地安装 Yarn 1 (Classic) 通常作为 npm 的全局依赖安装。安装说明请参见 [Yarn 1 文档](https://classic.yarnpkg.com/en/docs/getting-started)。 #### EAS 安装 如果项目目录包含 **yarn.lock**,则默认支持。 ### Yarn 2+ (Modern) #### 本地安装 安装说明请参见 [Yarn 文档](https://yarnpkg.com/getting-started/install)。 Yarn 2+ 处理包管理的方式与 Yarn 1 不同。Yarn 2+ 的核心变化之一是 [Plug'n'Play (PnP)](https://yarnpkg.com/features/pnp) 节点链接模型,而该模型无法与 React Native 配合使用。 默认情况下,使用 `create-expo-app` 和 Yarn 2+ 创建的项目会使用 [`nodeLinker`](https://yarnpkg.com/features/linkers#nodelinker-node-modules),并将其值设为 `node-modules` 来安装依赖。 ```yaml nodeLinker: node-modules ``` #### EAS 安装 EAS 上的 Yarn Modern 需要为构建启用 [Corepack](https://github.com/nodejs/corepack)。在 **eas.json** 的构建配置中将 [`corepack`](/eas/json#corepack) 设为 `true`: ```json { "build": { "production": { "corepack": true } } } ``` 然后,使用 [`packageManager`](https://nodejs.org/api/packages.html#packagemanager) 字段在项目的 **package.json** 中固定 Yarn 版本。在本地运行 `yarn set version ` 会为你更新此字段: ```json { "packageManager": "yarn@4.14.1" } ``` 添加以上两项配置后,当 EAS 安装依赖时,Corepack 会自动下载并使用固定的 Yarn 版本。 ### pnpm #### 本地安装 需要安装 Node.js。安装说明请参见 [pnpm 文档](https://pnpm.io/installation)。 默认情况下,使用 `create-expo-app` 和 pnpm 创建的项目会使用 [`nodeLinker`](https://pnpm.io/settings#nodelinker),并将其值设为 `hoisted` 来安装依赖。 ```yaml nodeLinker: hoisted ``` > **信息** 在 **SDK 54** 及更高版本中,Expo 支持隔离安装,如果你更喜欢使用隔离依赖,可以删除 `nodeLinker` 设置。 #### EAS 安装 如果项目目录包含 **pnpm-lock.yaml**,则默认支持。 ### Bun 有关使用 `bun` 创建新的 Expo 项目、从其他包管理器迁移以及在 EAS 中使用的详细信息,请参见 [Bun](/guides/using-bun) 指南。 --- --- title: Expo CLI description: Expo CLI 是一个命令行工具,是开发者与其他 Expo 工具之间的主要接口。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/more/expo-cli/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # Expo CLI Expo CLI 是一个命令行工具,是开发者与其他 Expo 工具之间的主要接口。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. `expo` 包提供了一个小巧而强大的 CLI 工具 `npx expo`,旨在帮助你在应用开发过程中保持高效推进。 ## 亮点 - 为开发你的应用 [启动服务器](/more/expo-cli#develop):`npx expo start`。 - 为你的项目 [生成原生 Android 和 iOS 目录](/more/expo-cli#prebuild):`npx expo prebuild`。 - 在本地 [构建并运行](/more/expo-cli#compiling) 原生应用:`npx expo run:ios` 和 `npx expo run:android`。 - [安装和更新](/more/expo-cli#install) 与项目中 `react-native` 版本兼容的包:`npx expo install package-name`。 - `npx expo` 可以与 `npx react-native` 同时使用。 要查看 Expo CLI 中可用命令的列表,请在你的项目中运行以下命令: ```sh npx expo -h ``` > 如果你更喜欢使用 yarn 作为包管理器,也可以运行 `yarn expo -h`。 输出应如下所示: ```sh Usage $ npx expo Commands start, export run:ios, run:android, prebuild install, customize, config login, logout, whoami, register Options --version, -v 版本号 --help, -h 使用信息 ``` 你可以使用 `--help` 或 `-h` 标志运行任何命令来了解更多信息: ```sh npx expo login -h ``` ## 安装 Expo CLI 包含在 `expo` 包中。你可以使用 npm 或 yarn 安装它: ```sh yarn add expo ``` > 未使用 [Expo Prebuild](/more/expo-cli#prebuild) 的项目(也称为 _Bare 项目_)需要进行额外设置,以确保所有自定义 Expo 打包功能正常工作:[Metro:Bare 工作流设置](/versions/latest/config/metro#bare-workflow-setup)。 ## 开发 通过运行以下命令启动开发服务器来处理你的项目: ```sh npx expo start ``` > 你也可以将 `npx expo` 作为 `npx expo start` 的别名来运行。 此命令会在 `http://localhost:8081` 上启动一个服务器,客户端可以通过它与打包器交互。默认的打包器是 [Metro](https://metrobundler.dev/)。 进程中显示的 UI 被称为 **终端 UI**。它包含一个二维码(用于开发服务器 URL)以及你可以按下的一组键盘快捷键: | 键盘快捷键 | 描述 | | --- | --- | | A | 在已连接的 Android 设备上打开项目。 | | Shift + A | 选择一个 Android 设备或模拟器来打开。 | | I | 在 iOS 模拟器中打开项目。 | | Shift + I | 选择一个 iOS 模拟器来打开。 | | W | 在网页浏览器中打开项目。这可能需要在你的项目中安装 webpack。 | | R | 在任何已连接设备上重新加载应用。 | | S | 在 Expo Go 和开发构建之间切换启动目标。 | | M | 在任何已连接的原生设备上打开开发菜单(不支持 web)。 | | Shift + M | 选择更多要在已连接设备上触发的命令。这包括切换性能监视器、打开元素检查器、重新加载设备以及打开开发菜单。 | | J | 为任何已连接且使用 Hermes 作为 JavaScript 引擎的设备打开 React Native DevTools。[了解更多](/guides/using-hermes#javascript-inspector-for-hermes)。 | | O | 在编辑器中打开项目代码。这可以通过 `EXPO_EDITOR` 和 `EDITOR` [环境变量](/more/expo-cli#environment-variables)进行配置。 | | E | 在终端中将开发服务器 URL 显示为二维码。 | | ? | 显示所有终端 UI 命令。 | ### 启动目标 如果项目中安装了 `expo-dev-client`,`npx expo start` 命令会自动在开发构建中启动应用。否则,它会在 Expo Go 中启动应用。 或者,你也可以通过向命令传递以下标志来强制指定启动目标: - `--dev-client`:始终以开发构建启动应用。 - `--go`:始终在 Expo Go 中启动应用。 你还可以在运行时通过在 **终端 UI** 中按下 S 来切换启动目标。默认情况下,`run` 命令在编译开发构建后也会使用 `--dev-client`。 ### 服务器 URL 默认情况下,项目通过局域网连接提供服务。你可以通过使用 `npx expo start --localhost` 标志将此行为更改为仅使用 localhost。 其他可用选项包括: - `--port`:启动开发服务器所使用的端口(不适用于 webpack 或 [隧道 URL](/more/expo-cli#tunneling))。使用 `--port 0` 可自动使用第一个可用端口。默认值:**8081**。 - `--https`:**(已弃用,推荐使用 `--tunnel`)** 使用安全来源启动开发服务器。目前仅支持 web。 你可以通过 `EXPO_PACKAGER_PROXY_URL` 环境变量强制将 URL 设置为任意值。例如: ```sh export EXPO_PACKAGER_PROXY_URL=http://expo.dev npx expo start ``` 将会打开应用到:`exp://expo.dev:80`(`:80` 是针对 Android WebSockets 的临时解决方法)。 #### 隧道 受限的网络条件(公共 Wi-Fi 中很常见)、防火墙(Windows 用户中很常见)或模拟器配置错误,都会使远程设备难以通过 lan/localhost 连接到你的开发服务器。 有时,通过一个任何设备在有互联网连接时都可访问的代理 URL 连接开发服务器会更容易,这被称为 **隧道**。`npx expo start` 通过 [ngrok](https://ngrok.com) 提供了对 **隧道** 的内置支持。 要启用隧道,首先安装 `@expo/ngrok`: ```sh npm i -g @expo/ngrok ``` 然后运行以下命令,通过一个 _隧道_ URL 启动你的开发服务器: ```sh npx expo start --tunnel ``` 这将通过如下公共 URL 提供你的应用:`https://xxxxxxx.bacon.19000.exp.direct:80`。 使用 `EXPO_TUNNEL_SUBDOMAIN` 环境变量可以实验性地设置隧道 URL 的子域名。这对于在 iOS 上测试通用链接很有用。这可能会导致 `expo-linking` 和 Expo Go 出现意外问题。通过传递一个 `string` 值来选择要使用的精确子域名,该值不能是以下之一:`true`、`false`、`1`、`0`。 **缺点** - 隧道比本地连接更慢,因为请求必须被转发到公共 URL。 - 隧道 URL 是公开的,任何有网络连接的设备都可以访问。Expo CLI 通过在 URL 开头添加随机性来降低暴露风险。你可以通过清空项目中的 **.expo** 目录来重置随机性。 - 隧道要求两台设备都具备网络连接,这意味着该功能不能与 `--offline` 标志一起使用。 隧道依赖第三方托管服务,这意味着它有时可能会遇到间歇性问题,例如 `ngrok tunnel took too long to connect` 或 `Tunnel connection has been closed. This is often related to intermittent connection problems with the Ngrok servers...`。在报告问题之前,请务必先检查 [Ngrok 服务状态](https://status.ngrok.com/)。一些 Windows 用户还报告称,需要修改他们的杀毒软件设置,以允许 Ngrok 正常工作。 #### 离线 你可以使用 `--offline` 标志在没有网络连接的情况下开发: ```sh npx expo start --offline ``` 离线模式会阻止 CLI 发出网络请求。如果你不使用该标志且你的电脑没有互联网连接,则会自动启用离线支持,只是验证连通性会多花一点时间。 Expo CLI 会发出网络请求,使用你的用户凭据对 manifest 进行签名,以确保敏感信息在 Expo Go 这类可复用运行时中处于沙箱隔离状态。 ### .expo 目录 当你第一次在项目中启动开发服务器时,项目根目录下会创建一个 **.expo** 目录。它包含两个文件: - **devices.json**:包含最近打开过该项目的设备信息。 - **settings.json**:包含用于提供项目 manifest 的服务器配置信息。 这两个文件都包含与你本地电脑相关的信息。这就是为什么在创建新项目时,默认情况下 **.expo** 目录会被包含到 **.gitignore** 文件中的原因。它并不打算与其他开发者共享。 ## 构建 一个 React Native 应用由两部分组成:一个原生运行时([编译](/more/expo-cli#compiling)),以及静态文件,例如 JavaScript bundle 和资源文件([导出](/more/expo-cli#exporting))。Expo CLI 提供了执行这两项任务的命令。 ### 编译 你可以使用 `run` 命令在本地编译你的应用: ```sh npx expo run:ios npx expo run:android ``` **亮点** - 使用 `--device` 标志可直接在已连接设备上构建,不会产生全局副作用。支持锁定设备,让你可以立即重试,而不必重新构建。 - 可通过 CLI 自动为开发环境对 iOS 应用进行代码签名,无需打开 Xcode。 - 智能日志解析会显示来自项目源代码的警告和错误,不像 Xcode 那样会显示来自 node_modules 的数百条无害警告。 - 导致应用崩溃的致命错误会直接显示在终端中,从而无需在 Xcode 中复现。 `npx expo run:ios` 只能在 Mac 上运行,并且必须安装 Xcode。你可以使用 `eas build -p ios` 从任何电脑在云端构建应用。同样,`npx expo run:android` 需要你的电脑上安装并配置好 Android Studio 和 Java。 在本地构建对于开发原生模块和[调试复杂的原生问题](/debugging/runtime-issues#native-debugging)很有用。由于预先配置好的云环境,使用 `eas build` 进行远程构建是一个更稳健的选择。 如果你的项目没有对应的原生目录,`npx expo prebuild` 命令会先运行一次,在构建之前生成相应的目录。 例如,如果你的项目根目录下没有 **ios** 目录,那么 `npx expo run:ios` 会先运行 `npx expo prebuild -p ios`,然后再编译你的应用。有关此过程的更多信息,请参见 [Expo Prebuild](/workflow/continuous-native-generation)。 **跨平台参数** - `--no-build-cache`: 在构建前清除原生缓存。在 iOS 上,这指的是 **derived data** 目录。清除缓存有助于分析构建耗时。 - `--no-install`: 跳过安装依赖。在 iOS 上,如果项目 `package.json` 中的 `dependencies` 字段发生变化,这也会跳过运行 `npx pod-install`。 - `--no-bundler`: 跳过启动开发服务器。如果开发服务器已经通过其他进程在提供应用,则会自动启用。 - `-d, --device [device]`: 要在哪个设备名称或 ID 上构建应用。你可以在不带参数的情况下使用 `--device`,从可用选项列表中选择一个设备。它支持已连接设备和虚拟设备。使用 `--device generic` 可在不针对特定设备的情况下构建(仅构建工作流)。 - `-o, --output `: 构建完成后,将生成的应用二进制文件复制到的目录。适用于 CI/CD 流水线,或当你希望二进制文件位于可预测位置时。 - `-p, --port `: 启动开发服务器的端口。**默认:8081**。这仅与开发构建相关。生产构建会先[导出](/more/expo-cli#exporting)项目,并在安装到设备前将文件嵌入原生二进制中。 - `--binary `: 要安装到设备上的二进制文件路径。提供此参数后,将跳过构建过程并尝试直接安装二进制文件。如果该二进制文件不是为正确设备构建的,例如它是为模拟器构建的或已安装到设备上,则命令会失败。 #### 编译 Android Android 应用可以有多个不同的 **变体**,它们在项目的 `build.gradle` 文件中定义。可以使用 `--variant` 标志选择变体: ##### `debug` 变体 使用 `debug` 变体进行调试构建: ```sh npx expo run:android --variant debug ``` ##### `debugOptimized` 变体 > **重要** `debugOptimized` 从 SDK 54 开始可用。 使用 `debugOptimized` 变体可以获得更快的开发体验,同时性能接近发布构建,并保持整体构建处于便于调试的模式: ```sh npx expo run:android --variant debugOptimized ``` 使用此变体时,请注意以下几点: - 如同发布构建一样优化 C++ 库,提升运行时性能 - 在 EAS Build 中,使用匹配的 Gradle 命令,例如 [`eas.json` 中的 `:app:assembleDebugOptimized`](/build-reference/apk#configuring-a-profile-to-build-apks) - **限制**:C++ 调试已禁用,C++ 崩溃可能具有可读性较差的堆栈跟踪 ##### `release` 变体 你可以通过运行以下命令为生产环境编译 Android 应用: ```sh npx expo run:android --variant release ``` 此构建不会自动进行代码签名,因此不能直接提交到 Google Play 商店。此命令应用于测试只会在生产构建中出现的 bug。要生成可为 Play 商店进行代码签名的生产构建,我们建议使用 [EAS Build](/build/introduction)。 ##### 调试原生 Android 项目 你可以通过在 Android Studio 中打开 **android** 目录,使用原生调试工具调试原生 Android 项目: ```sh open -a /Applications/Android Studio.app android ``` 如果你使用自定义的 Android 项目并配置了不同的 product flavor,你可以使用 `--variant` 和 `--app-id` 标志同时配置 flavor 和应用 ID: ```sh npx expo run:android --variant freeDebug --app-id dev.expo.myapp.free ``` 有关更多信息,请参见[使用 Android product flavors 进行本地构建](/guides/local-app-development#local-builds-using-android-product-flavors)指南。 #### 编译 iOS iOS 应用可以有多个 **scheme**,用于表示不同的子应用,例如 App Clip、watchOS 应用、Safari 扩展等。默认情况下,`npx expo run:ios` 会为你的 iOS 应用选择 scheme。你可以使用 `--scheme ` 参数选择自定义 scheme。如果你只传入 `--scheme` 参数,Expo CLI 会提示你从 Xcode 项目中可用的选项列表里选择一个 scheme。 你选择的 scheme 会过滤掉在选择提示中显示的 `--device` 选项,例如,选择 Apple TV scheme 时只会显示可用的 Apple TV 设备。 你可以通过运行以下命令为生产环境编译 iOS 应用: ```sh npx expo run:ios --configuration Release ``` 此构建不会自动进行代码签名,因此不能直接提交到 Apple App Store。`npx expo run:ios` 主要应用于测试只会在生产构建中出现的 bug。原生代码签名需要进行多次网络请求,并且容易受到 Apple 服务器上多种不同类型错误的影响。要生成可为 App Store 进行代码签名的生产构建,我们建议使用 [EAS Build](/build/introduction)。 当你将应用编译到模拟器上时,模拟器的原生日志会通过管道传输到终端中的 Expo CLI 进程。这对于快速查看可能导致致命错误的 bug 很有用,例如缺少权限的消息。物理 iOS 设备不支持错误输出管道传输。 你可以通过在 Xcode 中打开项目并从 Xcode 重新构建,使用 `lldb` 和所有 Apple 原生调试工具进行调试: ```sh xed ios ``` 从 Xcode 构建很有用,因为你可以设置原生断点并分析应用的任何部分。请务必在源代码管理(git)中跟踪更改,以防你需要使用 `npx expo prebuild -p ios --clean` 重新生成原生应用。 ##### 仅构建工作流 你可以使用 `generic` 设备选项,在不针对特定设备的情况下构建 iOS 模拟器应用: ```sh npx expo run:ios --device generic ``` 上述命令使用通用的 Xcode 目标(`generic/platform=iOS Simulator`),而不是特定的模拟器 UDID,这对于以下场景很有用: - **CI/CD 流水线**:在构建机上无需配置模拟器即可构建模拟器应用。 - **分发模拟器构建**:创建可共享并可在任何兼容模拟器上运行的 **.app** 包。 - **仅构建工作流**:当你只需要编译后的二进制文件,而不需要安装或启动时。 构建完成后,CLI 会输出生成的 **.app** 包路径: ```sh ✓ 构建完成 Binary: ~/Library/Developer/Xcode/DerivedData/.../Release-iphonesimulator/MyApp.app ``` 你可以将其与 `--configuration Release` 组合,创建生产模拟器构建,并使用 `--output` 将二进制文件复制到指定目录: ```sh npx expo run:ios --configuration Release --device generic --output ./build ``` 上述命令会将生成的 **.app** 包复制到 **./build/MyApp.app**。 **iOS 开发签名** 如果你想看看应用在设备上的运行方式,只需连接设备,运行 `npx expo run:ios --device`,然后选择你已连接的设备即可。 Expo CLI 会自动为开发环境对设备进行签名、安装应用并启动它。 如果你的电脑上没有设置任何开发者配置文件,那么你需要按照此指南在 Expo CLI 之外手动设置它们:[设置 Xcode 签名](https://expo.fyi/setup-xcode-signing)。 ### 导出 你可以通过运行以下命令,使用 Metro bundler 导出应用的 JavaScript 和资源文件: ```sh npx expo export ``` 在使用 `eas update` 或编译原生运行时时,这会自动完成。`export` 命令的工作方式与大多数 Web 框架类似: - bundler 会将应用代码转译并打包到 **生产** 环境中,剥离所有受 `__DEV__` 布尔值保护的代码。 - 所有静态文件都会被复制到静态 **dist** 目录中,可由静态主机提供服务。 - **public** 目录中的内容会按原样复制到 **dist** 目录中。 提供以下选项: - `--platform `: 选择要编译的平台:'ios'、'android'、'all'。**默认:all**。如果在 app 配置中进行了设置,也可以使用 'web'。更多信息请参见 [自定义 Metro](/guides/customizing-metro)。 - `--dev`: 为 **开发** 环境打包,不进行代码压缩,也不剥离 `__DEV__` 布尔值。 - `--output-dir `: 导出静态文件的目录。**默认:dist** - `--max-workers `: 允许 bundler 创建的最大任务数。将其设置为 `0` 会在同一进程中执行所有转译,这意味着你可以轻松调试 Babel 转译。 - `-c, --clear`: 在导出前清除 bundler 缓存。 - `--no-minify`: 跳过 JavaScript 和 CSS 资源的压缩。 - `--no-bytecode`: 跳过为原生平台生成 Hermes 字节码。仅在分析 bundle 大小时使用,切勿将 UTF-8 bundle 直接发布到原生平台,因为这会导致启动时间大幅延长。 - `--no-ssg`: 跳过为 Web 路由导出静态 HTML 文件。此选项仅在 **dist** 目录中生成服务器代码。适用于 [API 路由](/router/web/api-routes)。 #### 使用子路径托管 > **重要** [实验性](/more/release-statuses#experimental) 功能。 你可以通过在 [app 配置](/workflow/configuration) 中设置 `experiments.baseUrl` 字段来配置静态资源前缀: ```json { "expo": { "experiments": { "baseUrl": "/my-root" } } } ``` 这将导出一个所有资源都以前缀 `/my-root` 发布的网站。例如,位于 `assets/image.png` 的图片将预期托管在 **/my-root/assets/image.png**。实际文件将位于与服务器上预期托管在 `/my-root` 的整个目录相同的文件系统位置。 Expo Router 对 `baseUrl` 提供了内置支持。当使用 `Link` 和 `router` API 时,`baseUrl` 会自动添加到 URL 前面。 ```jsx import { Link } from 'expo-router'; export default function Blog() { return 前往博客文章; } ``` 这将 **导出** 为以下内容: ```html 前往博客文章 ``` 如果你直接使用 ``、React Navigation 或 `Linking` API,则需要手动在前面添加 `baseUrl`。 `baseUrl` 功能仅用于生产环境,且必须在导出网站之前设置。如果你更改了该值,必须重新导出网站。 如果你通过 `require` 或 `import` 引用图片和其他资源,它们会自动工作。如果你直接引用资源 URL,则需要手动追加 **baseUrl**。 ```jsx import { Image } from 'expo-image'; export default function Blog() { return ; } ``` 这将 **导出** 为以下内容: ```html ``` 如果手动传入 URL,则需要手动添加前缀: ```jsx export default function Blog() { return ; } ``` ### 使用 webpack 导出 > **警告** **[已弃用](/more/release-statuses#deprecated)**:从 SDK 50 开始,Expo Webpack 已被弃用,建议改用通用 Metro(`npx expo export`)。更多信息请参见[从 Webpack 迁移到 Expo Router](/router/migrate/from-expo-webpack)。 你可以通过运行以下命令,使用 webpack 导出 Web 应用的 JavaScript 和资源文件: ```sh npx expo export:web ``` - `--dev`: 以 'development' 模式打包,不进行代码压缩,也不剥离 `__DEV__` 布尔值。 - `-c, --clear`: 在导出前清除 bundler 缓存。 如果你的项目在 `app.json` 中通过 `expo.web.bundler: 'metro'` 字段配置为使用 `metro` 打包 Web 项目,则此命令将被禁用。 ## 预构建 ```sh npx expo prebuild ``` 在原生应用可以编译之前,必须先生成原生源代码。Expo CLI 提供了一个名为 _prebuild_ 的独特而强大的系统,它会为你的项目生成原生代码。要了解更多,请阅读 [Expo Prebuild 文档](/workflow/continuous-native-generation)。 ## 代码检查 ```sh npx expo lint ``` 代码检查有助于强制执行最佳实践,并确保你的代码保持一致。`npx expo lint` 命令会使用 Expo 特定设置来配置 ESLint,并运行针对 Expo 框架优化过选项的 `npx eslint` 命令。通过运行 `npx expo lint --fix`,代码检查问题可以自动修复。 默认情况下,运行 `npx expo lint` 会针对 **src**、**app** 和 **components** 目录中的所有文件。你也可以将自定义文件或目录作为参数传递给 lint 命令。例如: ```sh npx expo lint ./utils constants.ts ``` 默认情况下,所有匹配 `.js, .jsx, .ts, .tsx, .mjs, .cjs` 扩展名的文件都会被检查。你可以通过传递 `--ext` 标志来自定义扩展名。例如,要只检查 `.ts` 和 `.tsx` 文件,你可以使用 `--ext` 选项:`npx expo lint --ext .ts,.tsx` 或 `npx expo lint --ext .js --tsx .tsx`。 如果你需要更多自定义,可以使用 `--` 运算符传递额外参数。例如,要向 ESLint 传递 `--no-error-on-unmatched-pattern` 标志,可以运行: ```sh npx expo lint -- --no-error-on-unmatched-pattern ``` 如果你需要更多自定义,可以直接使用 `npx eslint`。 [使用 ESLint](/guides/using-eslint) — 了解更多关于在 Expo 项目中使用 ESLint 确保最佳实践的信息。 ## 配置 通过运行以下命令评估应用配置(**app.json**,或 **app.config.js**): ```sh npx expo config ``` - `--full`:包含所有项目配置数据。 - `--json`:以 JSON 格式输出,这对于将 **app.config.js** 转换为 **app.config.json** 很有用。 - `-t, --type`:[要显示的配置类型](/more/expo-cli#config-type)。 ### 配置类型 从应用配置中会生成三种不同的配置类型: - `public`:与 OTA 更新一起使用的清单文件。可以把它想象成原生应用中的 `index.html` 文件的 `` 元素。 - `prebuild`:由 [Expo Prebuild](/workflow/continuous-native-generation) 使用的配置,包括异步修饰器。这是配置不可序列化的唯一时机。 - `introspect`:`prebuild` 配置的一个子集,只显示内存中的修改,例如 `Info.plist` 或 **AndroidManifest.xml** 的更改。了解更多关于 [introspection](/config-plugins/development-and-debugging#introspection)。 ## 安装 与 Web 不同,React Native 不向后兼容。这意味着 npm 包通常需要与你项目中当前安装的 `react-native` 副本完全匹配正确的版本。Expo CLI 提供了一个尽力而为的工具,通过使用常用包列表和已知可用的版本组合来完成这项工作。只需使用 `install` 命令,就可以直接替代 `npm install`: ```sh npx expo install expo-camera ``` 运行该命令的单个实例时,你也可以安装多个包: ```sh npx expo install typescript expo-sms ``` 你可以使用 `--` 运算符直接向底层包管理器传递参数: ```sh yarn expo install typescript -- -D ``` ### 版本验证 你可以使用 `--check` 和 `--fix` 标志进行验证和修正: - `--check`:检查哪些已安装包需要更新。 - `--fix`:自动更新任何无效的包版本。 示例: ```sh npx expo install --check ``` `npx expo install --check` 会提示你哪些已安装包的安装不正确。它还会提示是否将这些包在本地安装为兼容版本。在持续集成(CI)中,它会以非零状态退出。这意味着你可以用它来进行持续的不可变验证。相较之下,`npx expo install --fix` 会在需要时始终修复包,不受环境影响。 你可以通过传入特定包来验证它们: ```sh npx expo install react-native expo-sms --check ``` 命令 `npx expo install expo-camera` 和 `npx expo install expo-camera --fix` 目的相同,`--fix` 命令适合用于升级项目中的所有包,例如: ```sh npx expo install --fix ``` ### 配置依赖验证 在某些情况下,你可能想使用一个不同于 `npx expo install` 所推荐版本的包版本。在这种情况下,你可以通过在项目的 **package.json** 中使用 [`expo.install.exclude`](/versions/latest/config/package-json#exclude) 属性,将特定包从版本检查中排除。 ### 安装包管理器 `npx expo install` 支持 `bun`、`npm`、`pnpm` 和 `yarn`。 你可以使用命名参数强制指定包管理器: - `--bun`:使用 `bun` 安装依赖。若存在 **bun.lockb** 或 **bun.lock**,则为默认值。 - `--npm`:使用 `npm` 安装依赖。若存在 **package-lock.json**,则为默认值。 - `--pnpm`:使用 `pnpm` 安装依赖。若存在 **pnpm-lock.yaml**,则为默认值。 - `--yarn`:使用 `yarn` 安装依赖。若存在 **yarn.lock**,则为默认值。 ## 身份验证 Expo CLI 提供可与 `npx expo start` 命令配合使用的身份验证方法。身份验证用于对清单进行“代码签名”,以便安全地使用 OTA。可以把它理解为 Web 上的 HTTPS。 1. 使用 `npx expo register` 注册账户。 2. 使用 `npx expo login` 登录你的账户。 3. 使用 `npx expo whoami` 查看当前已认证的是哪个账户。 4. 使用 `npx expo logout` 退出登录。 这些凭据在 Expo CLI 和 EAS CLI 之间共享。 ## 自定义 有时你可能希望自定义一个原本会由 Expo CLI 在内存中生成的项目文件。当使用 Expo CLI 之外的工具时,你需要保留默认配置文件,否则你的应用可能无法按预期运行。你可以通过运行以下命令生成文件: ```sh npx expo customize ``` 从这里,你可以选择生成如下基础项目文件: - **babel.config.js** -- Babel 配置。如果你计划使用 Expo CLI 之外的工具来打包项目,则必须存在此文件。 - **webpack.config.js** -- 用于 Web 开发的默认 webpack 配置。 - **metro.config.js** -- 用于通用开发的默认 Metro 配置。`npx react-native` 需要使用它。 - **tsconfig.json** -- 创建一个 TypeScript 配置文件并安装所需依赖。 ## 环境变量 | 名称 | 类型 | 描述 | | --- | --- | --- | | `HTTP_PROXY` | **string** | 用于连接所有网络请求的 HTTP/HTTPS 代理 URL。配置 [Undici EnvHttpProxyAgent](https://github.com/nodejs/undici/blob/main/docs/docs/api/EnvHttpProxyAgent.md)。 | | `EXPO_NO_WEB_SETUP` | **boolean** | 阻止 CLI 在使用 Web 功能之前强制安装 Web 依赖(`react-dom`、`react-native-web`、`@expo/webpack-config`)。这对于你希望进行非标准 Web 开发的情况很有用。 | | `EXPO_OFFLINE` | **boolean** | 在适用时跳过所有网络请求。这在网络连接较差的环境中可加快开发速度。 | | `EXPO_NO_TYPESCRIPT_SETUP` | **boolean** | 阻止 CLI 在 `npx expo start` 时强制配置 TypeScript。更多信息请参阅 [TypeScript 指南](/guides/typescript)。 | | `DEBUG=expo:*` | **string** | 为 CLI 启用调试日志,你可以使用 [`debug` 约定](https://github.com/debug-js/debug#conventions) 来配置它。 | | `EXPO_DEBUG` | **boolean** | `DEBUG=expo:*` 的别名。 | | `EXPO_PROFILE` | **boolean** | 为 CLI 启用性能分析统计信息,这不会对你的应用进行性能分析。 | | `EXPO_NO_CACHE` | **boolean** | 禁用所有全局缓存。默认情况下,应用配置 JSON schema、用于模拟器和仿真器的 Expo Go 二进制文件,以及项目模板都会缓存在你机器上的全局 **.expo** 目录中。 | | `CI` | **boolean** | 启用后,CLI 将禁用交互功能,跳过可选提示,并在非可选提示上失败。示例:如果任何已安装包已过期,`CI=1 npx expo install --check` 将失败。 | | `EXPO_NO_TELEMETRY` | **boolean** | 禁用匿名使用情况收集。[了解更多关于遥测的信息](/more/expo-cli#telemetry)。 | | `EXPO_NO_GIT_STATUS` | **boolean** | 在诸如 `npx expo prebuild --clean` 之类可能有风险的操作期间,跳过关于 git 状态的警告。 | | `EXPO_NO_REDIRECT_PAGE` | **boolean** | 禁用用于选择应用的重定向页面。该页面会在用户安装了 `expo-dev-client` 时显示,并且使用 `npx expo start` 而不是 `npx expo start --dev-client` 启动项目。 | | `EXPO_PUBLIC_FOLDER` | **string** | 与 Metro 一起用于 Web 的公共目录路径。[了解更多关于自定义 Metro 的信息](/guides/customizing-metro)。默认值:`public` | | `EDITOR` | **string** | 在终端 UI 中按下 O 时要打开的编辑器名称。此值会被许多命令行工具使用。 | | `EXPO_EDITOR` | **string** | Expo 专用版本的 `EDITOR` 变量,在定义时具有更高优先级。 | | `EXPO_IMAGE_UTILS_NO_SHARP` | **boolean** | 禁用全局 Sharp CLI 安装的使用,改用更慢的 Jimp 包进行图像处理。这用于诸如 `npx expo prebuild` 生成应用图标的场景。 | | `EXPO_TUNNEL_SUBDOMAIN` | **boolean** | , Experimental禁用将 `exp.direct` 作为 `--tunnel` 连接的主机名。这启用 **https://** 转发,可用于在 iOS 上测试通用链接。这可能会导致 `expo-linking` 和 Expo Go 出现意外问题。通过传递一个不属于以下值的 `string` 值来选择要使用的精确子域:`true`、`false`、`1`、`0`。 | | `EXPO_METRO_NO_MAIN_FIELD_OVERRIDE` | **boolean** | 强制 Expo CLI 对所有平台使用项目 **metro.config.js** 中的 [`resolver.resolverMainFields`](https://metrobundler.dev/docs/configuration/#resolvermainfields)。默认情况下,Expo CLI 会对 Web 使用 `['browser', 'module', 'main']`(这是 webpack 的默认值),而对其他平台使用用户定义的 main fields。 | | ~`EXPO_NO_INSPECTOR_PROXY`~ | **boolean** | , Deprecated禁用经过定制、并增强支持 Chrome DevTools 协议的 inspector proxy。这包括对网络 inspector 的支持。 | | `EXPO_NO_CLIENT_ENV_VARS` | **boolean** | 防止将 `EXPO_PUBLIC_` 环境变量内联到客户端 bundle 中。 | | `EXPO_NO_DOTENV` | **boolean** | 阻止 Expo CLI 加载所有 `.env` 文件。 | | `EXPO_NO_METRO_LAZY` | **boolean** | 阻止向 Metro URL 添加 `lazy=true` 查询参数(`metro@0.76.3` 及更高版本)。这会禁用 `import()` 支持。 | | `EXPO_USE_TYPED_ROUTES` | **boolean** | 使用 `expo.experiments.typedRoutes` 在 Expo Router 中启用静态类型路由。 | | ~`EXPO_METRO_UNSTABLE_ERRORS`~ | **boolean** | , Deprecated禁用 Metro 打包错误的反向依赖堆栈跟踪。默认启用。 | | ~`EXPO_USE_METRO_WORKSPACE_ROOT`~ | **boolean** | , Deprecated: SDK 52+启用 Metro 的自动服务器根目录检测。这会将服务器根目录更改为工作区根目录。适用于 monorepo。 | | `EXPO_NO_METRO_WORKSPACE_ROOT` | **boolean** | , SDK 52+禁用 Metro 的自动服务器根目录检测。禁用后不会将服务器根目录更改为工作区根目录。启用它对 monorepo 很有用。 | | ~`EXPO_USE_UNSTABLE_DEBUGGER`~ | **boolean** | , Deprecated: SDK 52+启用 React Native 的实验性调试器。 | | `EXPO_ADB_USER` | **string** | 设置应与 ADB 命令中的 `--user` 一起传递的 `user` 编号。用于在具有多个配置文件的 Android 设备上安装 APK。默认值为 `0`。 | | `EXPO_NO_TELEMETRY_DETACH` | **boolean** | , SDK 51+在 `@expo/cli` 的主线程中发送遥测事件。这会导致 CLI 变慢,因为它需要等待所有事件发送完成。 | | `EXPO_UNSTABLE_ATLAS` | **boolean** | , Experimental, SDK 51+在开发或导出期间收集 Metro bundle 信息。从 SDK 53 开始,此环境变量已弃用,改用 `EXPO_ATLAS`。 | | `EXPO_ATLAS` | **boolean** | , SDK 53+在开发或导出期间收集 Metro bundle 信息。 | | `EXPO_NO_BUNDLE_SPLITTING` | **boolean** | , Experimental, SDK 51+在生产环境中禁用 Metro 在异步导入时拆分 chunk(仅限 web)。 | | `EXPO_USE_METRO_REQUIRE` | **boolean** | , SDK 52+启用 Expo 自定义的 Metro `require` 实现和基于 `string` 的模块 ID。这可以为 React Server Components 带来更好的调试体验和确定性的 ID。不支持旧版 RAM bundles。 | | `EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH` | **boolean** | , Experimental, SDK 52+启用急切打包模式,其中转换会在整个 bundle 创建完成后以未缓存方式运行。这是生产环境 tree shaking 所必需的,但对开发环境打包的优化较少。 | | `EXPO_UNSTABLE_TREE_SHAKING` | **boolean** | , Experimental, SDK 52+在所有平台上启用不稳定的 tree shaking 支持。更多细节请参阅 [tree shaking](/guides/tree-shaking)。 | | `EXPO_NO_REACT_NATIVE_WEB` | **boolean** | , Deprecated: SDK 56+启用实验模式,在该模式下 Web 上运行 Expo 应用不需要 React Native Web。 | | `EXPO_NO_DEPENDENCY_VALIDATION` | **boolean** | , SDK 52+通过 `npx expo install` 和 `npx expo start` 安装包时,禁用内置依赖验证。 | | `EXPO_WEB_DEV_HYDRATE` | **boolean** | 为 Web 项目在开发环境中启用 React hydration。这可以帮助你尽早发现 hydration 问题。 | | `EXPO_UNSTABLE_LIVE_BINDINGS` | **boolean** | , Experimental, SDK 54+在实验性的 import/export 支持中禁用 live binding。默认启用。live binding 可以改善循环依赖支持,但可能会导致性能略差。 | | `EXPO_UNSTABLE_LOG_BOX` | **boolean** | , Experimental, SDK 55+为原生应用启用实验性的 LogBox 错误覆盖层。Web 默认启用。 | | `EXPO_NO_QR_CODE` | **boolean** | 阻止 CLI 在控制台显示二维码。 | ## 遥测 Expo 开发工具会收集有关常规使用情况的匿名数据。这有助于我们了解某个功能何时未按预期工作。遥测是完全可选的,你可以通过使用 `EXPO_NO_TELEMETRY=1` 环境变量来选择退出。 --- --- title: 术语表 description: 文档中使用的非显而易见术语列表,涉及 Expo 或更广泛的跨平台开发。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/more/glossary-of-terms/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # 术语表 文档中使用的非显而易见术语列表,涉及 Expo 或更广泛的跨平台开发。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. ### Android 由 Google 赞助、供 **Android** 设备使用的移动操作系统。 ### App config 位于项目根目录中名为 **app.json**、**app.config.json**、**app.config.js** 或 **app.config.ts** 的文件。有关更多信息,请参阅 [app config 配置](/workflow/configuration)。 此文件用于以下目的: - 配置 [Expo CLI](/more/glossary-of-terms#expo-cli) 的工作方式。 - 在 EAS Update 中生成项目的公开 [manifest](/more/glossary-of-terms#manifest)(可把它理解为原生应用里的 **index.html**)。 - 列出会影响 `npx expo prebuild` 如何生成原生代码的 Expo [config plugins](/more/glossary-of-terms#config-plugin)。 ### app.json 一个 [app config](/more/glossary-of-terms#app-config) 文件。 ### Apple capabilities 由 Apple 提供的云服务。应用必须在 [Apple Developer Portal](/more/glossary-of-terms#apple-developer-portal) 中启用这些服务。 ### Apple Developer Portal Apple 用于管理应用代码签名的[官方网站](https://developer.apple.com/)。EAS Credentials 会自动处理开发者在开发应用时可能需要访问该网站的许多常见原因。 ### Auto capability signing EAS Build 的一项功能,可根据项目的 entitlements 文件自动启用或禁用 [Apple capabilities](/more/glossary-of-terms#apple-capabilities)。[了解更多](/build-reference/ios-capabilities)。 ### Autolinking 一种跨平台工具,用于通过原生包管理器自动将原生模块链接到原生应用。 - 在 Android 上,该工具用于 **android/app/build.gradle**,并在 [Gradle](/more/glossary-of-terms#gradle) 同步过程中调用。 - 在 iOS 上,该工具用于 [CocoaPods](/more/glossary-of-terms#cocoapods) 的 **ios/Podfile**,并在执行 `pod install` 时调用。 Autolinking 有两个版本:[Expo Autolinking](/more/glossary-of-terms#expo-autolinking) 和 [Community Autolinking](/more/glossary-of-terms#community-autolinking)。 默认的 [Prebuild template](/more/glossary-of-terms#prebuild-template) 包含对 [Expo Autolinking](/more/glossary-of-terms#expo-autolinking) 和 [Community Autolinking](/more/glossary-of-terms#community-autolinking) 分支的支持。 ### Babel 用于移除运行时 [JavaScript engine](/more/glossary-of-terms#javascript-engine) 中不可用语言特性的转译器。[Metro](/more/glossary-of-terms#metro-bundler) 内部使用 Babel。 项目可以通过修改项目目录中的 [**babel.config.js**](/versions/latest/config/babel) 文件来配置 Babel 的使用方式。在使用 [Expo CLI](/more/glossary-of-terms#expo-cli) 时,这个文件是可选的。Expo 项目应扩展默认的 Babel 预设 [`babel-preset-expo`](https://github.com/expo/expo/tree/main/packages/babel-preset-expo)。 ### Bare workflow 描述原生项目(位于 **android** 和 **ios** 目录中)在 Git 中进行版本管理并由手动维护的方式。这通常适用于**现有的“裸” React Native 应用**,你需要手动对原生项目进行更改。它具有较高的定制自由度,但也带来了较高的维护成本。 这与使用 [app config 和 prebuild](/workflow/continuous-native-generation) 相对,后者中的原生项目不进行版本管理。相反,它们会按需通过 `npx expo prebuild` 生成,这也是[推荐的方式](/workflow/continuous-native-generation)。 ### Bun 一个 JavaScript 运行时,也是 Node.js 的可直接替代方案。Bun 也可用作 [JavaScript 的包管理器](/more/glossary-of-terms#package-manager)。有关与 Expo 和 EAS 一起使用的更多信息,请参阅 [使用 Bun](/guides/using-bun) 指南。 ### CocoaPods 用于将原生模块链接到原生 iOS 项目的 iOS 包管理器。该包管理器通过 **ios/Podfile** 文件进行配置,并在用户于 **ios** 目录中运行 `pod install` 时更新。 ### Community Autolinking 这是 React Native 社区对 [Expo Autolinking](/more/glossary-of-terms#expo-autolinking) 的[fork](https://github.com/react-native-community/cli/issues/248#issue-422591744)。模块的链接需求与 [Expo Autolinking](/more/glossary-of-terms#expo-autolinking) 不同,但实现相同。 ### Config introspection 一种在内存中评估 [`npx expo prebuild`](/more/glossary-of-terms#prebuild) 结果而不持久化任何代码更改的过程。它用于 [Auto Capability Signing](/more/glossary-of-terms#auto-capability-signing),以在不生成任何原生代码的情况下确定 entitlements 文件的外观。该过程也用于 [VS Code Expo Tools](/more/glossary-of-terms#vs-code-expo-tools) 扩展中,以调试 [Config Mods](/more/glossary-of-terms#config-mods)。 ### Config Mods 附加到 [app config](/more/glossary-of-terms#app-config) 上、供 [Prebuild](/more/glossary-of-terms#prebuild) 使用的异步函数。这些函数会接受单个原生文件进行修改,例如 **AndroidManifest.xml** 或 **Info.plist**。Config mods 会串联起来,并来自 `@expo/config-plugins` 包。有关更多信息,请参阅 [Config plugins](/config-plugins/introduction)。 ### Config Plugin 用于将 [config mods](/more/glossary-of-terms#config-mods) 附加到 [app Config](/more/glossary-of-terms#app-config) 上、供 [Prebuild](/more/glossary-of-terms#prebuild) 使用的 JavaScript 函数。有关更多信息,请参阅 [Config Plugins](/config-plugins/introduction)。 ### Continuous Native Generation (CNG) 描述从一组输入生成原生项目的抽象概念。在 Expo 的语境中,CNG 通过 [`prebuild`](/more/glossary-of-terms#prebuild) 命令实现。更多信息请参阅 [Continuous Native Generation](/workflow/continuous-native-generation)。 ### create-expo-app 一个独立的命令行工具(CLI),用于启动已安装 `expo` 包的新 React Native 应用。更多信息请参阅 [`create-expo-app` 参考](/more/create-expo)。 ### create-react-native-app 一个独立的命令行工具(CLI),用于启动已安装 `expo` 包并生成原生代码的新 React Native 应用。该 CLI 还支持从 [expo/examples](https://github.com/expo/examples) 中的示例项目进行启动。 可以通过运行以下任一命令来使用此包: - `npx create-expo-app` - `yarn create expo-app` - `npm create expo-app` ### Dangerous mods 在 [prebuild](/more/glossary-of-terms#prebuild) 期间对原生项目应用不稳定更改的 [modifiers](/more/glossary-of-terms#config-mods)。使用这些修改器具有不可预测性,并且在 [Expo SDK](/more/glossary-of-terms#expo-sdk) 的主要版本升级之间容易出现破坏性变更。有关更多信息,请参阅 [Using a dangerous mod](/config-plugins/dangerous-mods)。 ### Development build 开发构建是包含 `expo-dev-client` 包的应用调试构建。它类似于 [Expo Go](/more/glossary-of-terms#expo-go) 的进化版,不受 Expo Go 的限制,并且可以根据应用需求进行定制。 这是使用 Expo 构建生产级应用的推荐方式。有关更多信息,请参阅 [Development builds](/get-started/set-up-your-environment?mode=development-build)。 ### Dev clients `expo-dev-client` 是一个允许你创建开发构建并包含实用开发工具的库。你也可能会遇到“custom dev client”这一说法,它是 [Development builds](/more/glossary-of-terms#development-build) 的同义词。 ### Development server 开发服务器(或 dev server)是本地启动的服务器,通常通过从 [Expo CLI](/more/glossary-of-terms#expo-cli) 运行 `npx expo start` 来启动。 开发服务器通常托管在 `http://localhost:8081`。它在 `/` 下提供一个 [manifest](/more/glossary-of-terms#manifest),客户端通过它来请求 bundler 提供的 JavaScript bundle。 ### Expo Application Services (EAS) [Expo Application Services (EAS)](/eas) 是为 Expo 和 React Native 应用深度集成的云服务,例如 [EAS Build](/build/introduction)、[EAS Submit](/submit/introduction)、[EAS Update](/eas-update/introduction)、[EAS Metadata](/eas/metadata)、[EAS Insights](/eas-insights/introduction)、[EAS Hosting](/eas/hosting/introduction) 和 [EAS Workflows](/eas/workflows/introduction)。 ### EAS Build [EAS Build](/build/introduction) 是 [EAS](/more/glossary-of-terms#expo-application-services-eas) 的云服务,用于为 Expo 和 React Native 应用构建 Android 和 iOS 二进制文件。EAS Build 可用于构建 [development builds](/more/glossary-of-terms#development-build) 和 [standalone apps](/more/glossary-of-terms#standalone-app)。 ### EAS CLI 用于与 EAS 协作的命令行工具。有关更多信息,请参阅 [EAS CLI](/eas/cli) 参考。 ### EAS Config 用于配置 [EAS CLI](/more/glossary-of-terms#eas-cli) 的 **eas.json** 文件。有关更多信息,请参阅 [使用 eas.json 配置 EAS Build](/build/eas-json)。 ### EAS Hosting [EAS Hosting](/eas/hosting/introduction) 是 [EAS](/more/glossary-of-terms#expo-application-services-eas) 的云服务,可快速部署使用 [Expo Router](/more/glossary-of-terms#expo-router) 和 [React Native Web](/more/glossary-of-terms#react-native-web) 构建的 Web 项目。 ### EAS Insights [EAS Insights](/eas-insights/introduction) 是 [EAS](/more/glossary-of-terms#expo-application-services-eas) 的云服务,为 Expo 项目提供使用情况、性能和覆盖范围信息。它使用 `expo-insights` 库将事件从应用发送到 EAS Insights。 ### EAS Metadata 一个用于以 JSON 形式上传和下载 Apple App Store 元数据的命令行工具。该工具可在 [EAS CLI](/more/glossary-of-terms#eas-cli) 包中使用,应当用于改进 iOS 提交流程。有关更多信息,请参阅 [EAS Metadata](/eas/metadata)。 ### EAS Update 1. 来自 [EAS](/more/glossary-of-terms#expo-application-services-eas) 的云托管服务 [EAS Update](/eas-update/introduction),用于 OTA 更新。 2. 来自 [EAS CLI](/more/glossary-of-terms#eas-cli) 的 CLI 命令 `eas update`,用于将静态文件发布到云托管服务。 ### EAS Workflows [EAS Workflows](/eas/workflows/introduction) 是 [EAS](/more/glossary-of-terms#expo-application-services-eas) 的 CI/CD 服务,可让团队自动化重复任务,例如构建 Android 和 iOS 二进制文件、发布空中更新、提交到应用商店、使用 Maestro 运行 E2E 测试,以及将 Web 应用部署到 [EAS Hosting](/eas/hosting/introduction)。Workflows 通过 **.eas/workflows** 目录下的 YAML 文件进行配置。 ### Emulator Emulator 用于描述计算机上的 Android 设备软件模拟器。通常,iOS 模拟器被称为 [Simulator](/more/glossary-of-terms#simulator)。 ### Entry point entry point 通常指用于加载应用的初始 JavaScript 文件。在使用 [Expo CLI](/more/glossary-of-terms#expo-cli) 的应用中,默认入口点是 **./node_modules/expo/AppEntry.js**,它会简单地从项目根目录导入 **App.js** 文件,并将其注册为原生应用中的初始组件。 ### Experience 应用的同义词,通常暗示其更偏向一次性使用且范围更小,有时带有艺术性和奇趣风格。 ### Expo Atlas [Expo Atlas](/atlas/introduction) 是一个用于可视化 JavaScript bundle 的工具。它可用于检查 bundle 大小,并识别哪些库对生产 bundle 有贡献。 ### Expo Autolinking 原始的 [Autolinking](/more/glossary-of-terms#autolinking) 系统是为使用 `expo-modules-core` 的项目设计的。该系统根据库根目录中是否存在 **expo-module.config.json** 来链接模块。 ### Expo CLI 用于与 Expo 协作的命令行工具。此术语现在指 [Local Expo CLI](/more/glossary-of-terms#local-expo-cli),但历史上指的是 [Global Expo CLI](/more/glossary-of-terms#global-expo-cli)。有关更多信息,请参阅 [Expo CLI](/more/expo-cli)。 ### Expo client [Expo Go](/more/glossary-of-terms#expo-go) 应用的旧名称。 ### Expo Doctor [Expo Doctor](/develop/tools#expo-doctor) 是一个用于诊断 Expo 项目问题的命令行工具。使用时,请在项目目录中运行 `npx expo doctor`。 ### Expo export 指来自 [Expo CLI](/more/glossary-of-terms#expo-cli) 的命令 `npx expo export`。该命令用于打包应用的 JavaScript 和资源,然后将它们导出到一个静态目录中,静态目录可上传到 [EAS Update](/more/glossary-of-terms#eas-update) 等托管服务,并嵌入到 [native runtime](/more/glossary-of-terms#native-runtime) 中供离线使用。 ### Expo Fingerprint [`@expo/fingerprint`](/versions/latest/sdk/fingerprint) 库会对决定项目原生构建的文件和配置进行哈希处理(应用依赖、定制原生代码、原生项目文件和配置)。该哈希代表原生层状态,因此工具可以在不重新构建的情况下判断某个 TypeScript/JavaScript bundle 是否与给定构建兼容。主要用于 EAS Update 的 fingerprint runtime version policy,以及用于 CI/CD 自动化的 EAS Workflows。 ### Expo Go Android 和 iOS 应用,用作学习和试验 React Native 的沙盒环境。 由于其限制(例如无法包含自定义原生代码),不建议用于构建和分发生产应用。相反,请使用 [development build](/more/glossary-of-terms#development-build)。 ### Expo install 指来自 [Expo CLI](/more/glossary-of-terms#expo-cli) 的命令 `npx expo install`。该命令用于安装包含可与项目当前安装的 `expo` 版本配合使用的 [native modules](/more/glossary-of-terms#native-module) 的 npm 包。并非所有包都受支持。该命令封装了全局安装的 [package managers](/more/glossary-of-terms#package-manager)。 ### Expo MCP server [Expo MCP(Model Context Protocol)服务器](/eas/ai/mcp) 是 Expo 托管的远程服务器,可与 Claude Code、Cursor、VS Code 等 AI 辅助工具集成。它使这些工具能够直接与您的 Expo 项目交互。 ### Expo Module Config 位于 [native module](/more/glossary-of-terms#native-module) 根目录中的名为 **expo-module.config.json** 的文件。有关更多信息,请参阅 [Module Config](/modules/module-config)。 ### Expo Modules API [Expo Modules API](/modules/module-api) 是一个跨平台 API,用于用 Kotlin 和 Swift 编写原生模块,为你的应用添加新能力。该 API 由库 `expo-modules-core` 提供,而该库包含在 `expo` 包中。 ### Expo Orbit [Expo Orbit](/build/orbit) 是一款适用于 macOS 和 Windows 的应用,可更快地在设备或模拟器上安装并启动来自 EAS、本地文件或 Snack 项目的构建或更新。 ### Expo Router [Expo Router](/router/introduction) 是适用于 React Native 和 Web 应用的基于文件的路由器。它允许你管理应用中各屏幕之间的导航,使用户能够通过在多个平台(Android、iOS 和 Web)上使用相同的组件,无缝地在应用 UI 的不同部分之间移动。 ### Expo SDK 一组包含 [native modules](/more/glossary-of-terms#native-module) 的 [npm](/more/glossary-of-terms#npm) 包,为相机、推送通知、联系人、文件系统等设备/系统功能提供访问能力。 - 在可能的情况下,每个包都支持 Android、iOS 和 web。 - 接口完全使用 [TypeScript](/more/glossary-of-terms#typescript) 编写。 - Expo SDK 中的所有包彼此兼容,并且可以安全地一起编译。 - SDK 中的任何包都可以在任何 [React Native](/more/glossary-of-terms#react-native) 应用中使用,只需最少且共享的设置。[了解更多](/bare/installing-expo-modules)。 - 所有包都是[开源](https://github.com/expo/expo/tree/main/packages)的,可以自由定制。 ### Expo start 指来自 [Expo CLI](/more/glossary-of-terms#expo-cli) 的命令 `npx expo start`。该命令用于启动本地 [development server](/more/glossary-of-terms#development-server),由 [client](/more/glossary-of-terms#expo-client) 连接以与 [Metro bundler](/more/glossary-of-terms#metro-bundler) 交互。 ### Fabric React Native 的渲染系统,用于创建和管理原生视图。有关更多信息,请参阅 [Fabric Renderer](https://reactnative.dev/architecture/fabric-renderer)。 ### FYI 有时也称为 **Expo FYI**,是位于 [expo.fyi](https://expo.fyi/) 的一系列针对复杂问题的定制解决方案。FYI 链接被广泛用于 Expo 的开发者工具中,以帮助为用户提供更好的开发体验。 ### Gradle Gradle 是一种用于多语言软件开发的构建自动化工具。它用于构建 Android 应用。它在编译、打包、测试、部署和发布等任务中控制开发流程。 ### Hermes engine 由 [Meta](/more/glossary-of-terms#meta) 专为 [React Native](/more/glossary-of-terms#react-native) 使用而开发的 [JavaScript engine](/more/glossary-of-terms#javascript-engine)。Hermes 具有提前静态优化和紧凑字节码,以提升面向移动设备的性能,并且是默认的 JS 引擎。 ### iOS 用于 iPhone、iPad 和 Apple TV 的操作系统。[Expo Go](/more/glossary-of-terms#expo-go) 目前运行于 iPhone 和 iPad 的 iOS 上。 ### JavaScript engine 一种可在设备上执行 JavaScript 的原生包。在 React Native 中,我们主要使用 [Meta](/more/glossary-of-terms#meta) 的 [Hermes](/more/glossary-of-terms#hermes-engine)。其他选项包括 Apple 的 [JavaScriptCore](/more/glossary-of-terms#javascriptcore-engine) 以及 Google 的 V8。 ### JavaScriptCore engine 由 Apple 开发并内置于 [iOS](/more/glossary-of-terms#ios) 的 [JavaScript engine](/more/glossary-of-terms#javascript-engine)。React Native for [Android](/more/glossary-of-terms#android) 也可以使用一个版本的 JavaScriptCore 以保持一致性。使用 JavaScriptCore 进行调试不如实现了 [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/) 的 V8 或 [Hermes](/more/glossary-of-terms#hermes-engine) 那么成熟。 ### Linking Linking 可以指 [类似于在 Web 上链接到网站那样,深度链接到应用中](/linking/overview),也可以指 [autolinking](/more/glossary-of-terms#autolinking)。 ### Local Expo CLI 包 `@expo/cli` 会随着 `expo` 包一起安装。这有时被称为“版本化 Expo CLI”,因为它安装在用户的项目中,而不是已弃用的、全局安装的 `expo-cli`。 ### Manifest Expo 应用 manifest 类似于 [web app manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest)。它提供 Expo Go 需要知道如何运行应用的信息以及其他相关数据。 ### Meta Meta 曾用名 Facebook,是开发 [React Native](/more/glossary-of-terms#react-native)、[Metro Bundler](/more/glossary-of-terms#metro-bundler)、[Hermes Engine](/more/glossary-of-terms#hermes-engine)、[Yoga](/more/glossary-of-terms#yoga) 等项目的公司。Expo 团队与 Meta 合作,以提供尽可能好的开发者体验。 ### Metro bundler 用于将 JavaScript 文件和资源转换为可在 [native runtime](/more/glossary-of-terms#native-runtime) 上运行的格式的 bundler。该 bundler 由 [Meta](/more/glossary-of-terms#meta) 维护,并用于 React Native(包括 web)应用。有关更多信息,请参阅 [Metro documentation](https://metrobundler.dev/)。 ### Metro config 用于配置 [Metro bundler](/more/glossary-of-terms#metro-bundler) 的 **metro.config.js** 文件。在使用 [Expo CLI](/more/glossary-of-terms#expo-cli) 时,这应扩展包 `@expo/metro-config`。有关更多信息,请参阅 [Customizing Metro](/guides/customizing-metro)。 ### Monorepo 一个包含多个子项目、并通过包管理器相互关联的项目。Monorepo 是维护跨平台应用代码库的绝佳方式。 ### Native directory React Native 生态系统有成千上万的库。如果没有专门构建的工具,就很难了解这些库是什么、搜索它们、判断质量、试用它们,以及筛选出不适合你项目的库(有些不适用于 Expo,有些不适用于 Android 或 iOS)。[React Native Directory](https://reactnative.directory/) 是一个旨在解决这一问题的网站,我们建议你使用它来寻找项目中要使用的包。 ### Native module 用原生代码编写的模块,通过 JS 全局对象向 JavaScript 引擎暴露原生平台功能。通常通过 `import { NativeModules } from 'react-native';` 访问这些功能。 ### Native runtime 包含 [JavaScript engine](/more/glossary-of-terms#javascript-engine) 且能够运行 React 应用的原生应用。这包括 [Expo Go](/more/glossary-of-terms#expo-go)、[development build](/more/glossary-of-terms#development-build)、[standalone apps](/more/glossary-of-terms#standalone-app),甚至像 Chrome 这样的 Web 浏览器。 ### npm [npm](https://www.npmjs.com/) 是 [JavaScript 的包管理器](/more/glossary-of-terms#package-manager) 以及存放这些包的注册表。 ### Package manager 自动化安装、升级、配置和移除项目中库(也称为依赖项)的过程。参见 [Bun](/more/glossary-of-terms#bun)、[npm](/more/glossary-of-terms#npm)、[pnpm](/more/glossary-of-terms#pnpm) 和 [Yarn](/more/glossary-of-terms#yarn)。 ### Package manager workspaces Expo 用户推荐的 [monorepo](/more/glossary-of-terms#monorepo) 方案。有关如何为受支持的包管理器配置 workspaces 的更多信息,请参阅 [使用 Monorepo](/guides/monorepos) 指南。 ### Platform extensions Platform extensions 是 [Metro bundler](/more/glossary-of-terms#metro-bundler) 的一项功能,它允许用户根据特定文件名按平台替换文件。例如,如果一个项目有 **.index.js** 文件和 **.index.ios.js** 文件,那么在为 iOS 打包时会使用 **index.ios.js**,而在为所有其他平台打包时会使用 **index.js** 文件。 默认情况下,platform extensions 会在 `@expo/metro-config` 中按照以下公式解析: - Android: **\*.android.js**, **\*.native.js**, **\*.js** - iOS: **\*.ios.js**, **\*.native.js**, **\*.js** - Web: **\*.web.js**, **\*.js** ### pnpm [pnpm](https://pnpm.io/) 是一个 [JavaScript 的包管理器](/more/glossary-of-terms#package-manager),专注于提高磁盘空间效率。 ### Prebuild 根据 [应用配置](/more/glossary-of-terms#app-config) 为 React Native 项目生成临时的本地 **android** 和 **ios** 目录的过程。该过程通过在项目目录中从 [Expo CLI](/more/glossary-of-terms#expo-cli) 运行命令 `npx expo prebuild` 来执行。 有关更多信息,请参见 [Prebuild 模板](/more/glossary-of-terms#prebuild-template) 和 [自动链接](/more/glossary-of-terms#autolinking)。 ### Prebuild 模板 React Native 项目模板作为 [Prebuild](/more/glossary-of-terms#prebuild) 的第一步使用。该模板会随 [Expo SDK](/more/glossary-of-terms#expo-sdk) 进行版本控制,并且模板会根据项目中安装的 `expo` 版本来选择。模板克隆完成后,`npx expo prebuild` 会评估 [应用配置](/more/glossary-of-terms#app-config) 并运行会修改模板中各种文件的 [配置修改](/more/glossary-of-terms#config-mods)。 虽然可以使用 `npx expo prebuild --template /path/to/template` 标志来更改模板,但默认的 prebuild 模板包含 `npx expo prebuild` 命令所依赖的重要初始默认值。 默认模板目前位于 [`expo-template-bare-minimum`](https://github.com/expo/expo/tree/main/templates/expo-template-bare-minimum)。 ### 发布 我们将“publish”作为“deploy”的同义词使用。当你发布一个应用时,它会通过 Expo Go 变为可通过一个持久 URL 访问;或者在 [独立应用](/more/glossary-of-terms#standalone-app) 的情况下,它会更新该应用。 ### React Native [React Native](https://reactnative.dev/) 让你只用 JavaScript 就能构建移动应用。它使用与 React 相同的设计,使你能够通过声明式组件组合出丰富的移动 UI。 ### React Native Web 建立在 `react-dom` 之上的高性能抽象层,使 [React Native](/more/glossary-of-terms#react-native) 的核心原语能够在浏览器中运行。面向 Web 的 React Native(RNW)由 X 开发,目前用于他们的 [主站](https://x.com)。[Expo SDK](/more/glossary-of-terms#expo-sdk) 和 [Expo CLI](/more/glossary-of-terms#expo-cli) 对 RNW 提供一等支持。 ### React Navigation React Native 应用首选的导航库,由 Expo 团队开发并赞助。 ### 远程调试 远程调试是 React Native 应用的一种已弃用的调试方式。如今更好的替代方案是使用 [Hermes](/more/glossary-of-terms#hermes-engine),因为你可以将 React Native DevTools 连接到它。 它也被称为 Async Chrome 调试,是一种用于调试 React Native 应用的实验性系统。该系统通过在 Chrome 标签页的 web worker 中执行应用的 JavaScript,然后通过 websocket 将原生命令发送到原生设备来工作。 ### 模拟器 iOS 设备模拟器,可在 macOS 上运行(或在 [Snack](/more/glossary-of-terms#snack) 中运行),让你在没有实体设备的情况下开发应用。 ### Slug [应用配置](/more/glossary-of-terms#appjson) 中的 `slug` 是项目的一个便于 URL 使用的名称。它在你的 Expo 账户中是唯一的。 ### Snack [Snack](https://snack.expo.dev/) 是一个基于浏览器的开发环境,你可以在其中构建 Expo [体验](/more/glossary-of-terms#experience),而无需在手机或电脑上安装任何工具。 ### Software Mansion 位于波兰克拉科夫的一家开发机构。`react-native-gesture-handler`、`react-native-screens` 和 `react-native-reanimated` 的维护者。Expo 的平台团队由来自 Software Mansion 的多名外包人员组成。Software Mansion 的所有核心 React Native 库都在 [Expo Go](/more/glossary-of-terms#expo-go) 中受支持。 ### 独立应用 “生产构建”的同义词。可提交到 Google Play 商店或 Apple App Store 的应用二进制文件。更多信息请参见 [为应用商店构建项目](/deploy/build-project) 或 [在本地或自有基础设施上运行构建](/build-reference/local-builds)。 ### 商店配置 用于配置 [EAS Metadata](/more/glossary-of-terms#eas-metadata) 的 **store.config.json** 文件。该文件可以通过现有的 App Store 条目使用 `eas metadata:pull` 生成。 ### Sweet API 用于编写 React Native 模块的 Swift 和 Kotlin API。此 API 由库 `expo-modules-core` 提供,而该库随 `expo` 包一同发布。更多信息请参见 [模块 API](/modules/module-api)。 ### TypeScript TypeScript 是一种强类型编程语言,建立在 JavaScript 之上,可为任何规模的项目提供更好的工具支持。Expo SDK 使用 TypeScript 编写,我们强烈推荐使用它。更多信息请参见我们的 [TypeScript 指南](/guides/typescript)。 ### 更新 传统上,Android 和 iOS 应用的更新方式是向 App Store 和 Play 商店提交一个更新后的二进制文件。Updates 允许你向应用推送更新,而无需承担向商店提交新版本的开销。更多信息请参见 [发布](/eas-update/introduction) 文档。 ### VS Code Expo Tools 用于改善开发者在处理应用配置文件时体验的 VS Code 扩展。此扩展为 [应用配置](/more/glossary-of-terms#app-config)、[商店配置](/more/glossary-of-terms#store-config)、[Expo 模块配置](/more/glossary-of-terms#expo-module-config) 和 [EAS 配置](/more/glossary-of-terms#eas-config) 提供自动补全和智能提示。更多信息请参见 [VS Code Expo Tools 扩展](https://marketplace.visualstudio.com/items?itemName=expo.vscode-expo-tools)。 ### Watchman [Metro](/more/glossary-of-terms#metro-bundler) 用于在开发期间执行热重载的文件监视器。Watchman 包含原生代码,若全局安装可能会导致问题。Watchman 由 [Meta](/more/glossary-of-terms#meta) 维护。 ### webpack [Expo CLI](/more/glossary-of-terms#expo-cli) 用于开发 [`react-native-web`](/more/glossary-of-terms#react-native-web) 应用的已弃用打包器。 ### Yarn [Yarn](https://yarnpkg.com/) 是一个由 Meta 创建的 [JavaScript 的包管理器](/more/glossary-of-terms#package-manager)。它有两个主线版本:[Yarn v1(Classic)](https://classic.yarnpkg.com/lang/en/) 和 [Yarn Berry](https://github.com/yarnpkg/berry)。 ### Yoga React Native 内部使用的原生跨平台库,用于向原生视图提供 [CSS FlexBox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox) 支持。React Native 的样式会传递给 Yoga,以对屏幕上的元素进行布局和样式设置。更多信息请参见 [Yoga](https://github.com/facebook/yoga) 文档。 --- --- title: qr.expo.dev description: qr.expo.dev 上二维码生成器的参考文档。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/more/qr-codes/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # qr.expo.dev qr.expo.dev 上二维码生成器的参考文档。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. qr.expo.dev 是一个生成带有 Expo 品牌的 QR 码的云函数。该函数会为 [EAS Update](/eas-update/introduction) 创建 QR 码,这些 QR 码用于在 [开发构建](/develop/development-builds/introduction) 和 Expo Go 中预览更新。 例如,如果你和你的团队有一个开发构建,并且你想在某个构建的频道上加载最新更新,你可以前往以下端点生成 QR 码: ```text https://qr.expo.dev/eas-update?projectId=your-project-id&runtimeVersion=your-runtime-version&channel=your-channel ``` 这将生成以下 QR 码 SVG: 这个 QR 码代表以下 URL: ```text exp+your-slug://expo-development-client/?url=https://u.expo.dev/your-project-id?runtime-version=your-runtime-version&channel-name=your-channel ``` 此 URL 会深度链接到一个开发构建,并指示它获取指定频道上的最新更新。 > 如果共享 URL 更方便,你可以在查询参数中添加 `format=url` 来直接请求 URL。 ## General 以下参数适用于 `/eas-update` 端点。 ### Base query parameters 以下基础查询参数可以包含在发往 `/eas-update` 的任何请求中。 | Param | Required | Default | Description | | --- | --- | --- | --- | | `slug` | No | exp | 使用 [app config](/workflow/configuration) 中的 [`slug`](/versions/latest/config/app#slug) 来定位开发构建。否则使用 "exp" 来定位 Expo Go。 | | `appScheme` (deprecated) | No | exp | 已被 `slug` 替换。请改用 `slug`。 | | `host` | No | u.expo.dev | 处理更新请求的服务器主机名。 | | `format` | No | svg | 端点默认返回 SVG。若要接收纯文本 URL,请使用 `url`。 | ### Update by device traits 预览和生产构建会向 EAS Update 服务发出带有 `runtimeVersion` 和 `channel` 属性的请求。你可以使用以下查询参数模拟这种行为: | Param | Required | Description | | --- | --- | --- | | `projectId` | Yes | 项目的 ID | | `runtimeVersion` | Yes | 构建的 [runtime version](/eas-update/runtime-versions) | | `channel` | Yes | 构建的频道名称 | #### Example ```text https://qr.expo.dev/eas-update?projectId=your-project-id&runtimeVersion=your-runtime-version&channel=your-channel ``` ### Update by ID 你可以为给定的平台特定 ID 创建一个特定更新的 QR 码。 | Param | Required | Description | | --- | --- | --- | | `updateId` | Yes | 更新的 ID | #### Example ```text https://qr.expo.dev/eas-update?updateId=your-update-id ``` ### Update by group ID 你可以为给定的更新组 ID 创建一个更新组的 QR 码。 | Param | Required | Description | | --- | --- | --- | | `projectId` | Yes | 项目的 ID | | `groupId` | Yes | 更新组的 ID | #### Example ```text https://qr.expo.dev/eas-update?projectId=your-project-id&groupId=your-update-id ``` ### Update by branch ID 你可以使用分支的 ID 创建一个 QR 码,它将返回该分支上可用的最新更新。 | Param | Required | Description | | --- | --- | --- | | `projectId` | Yes | 项目的 ID | | `branchId` | Yes | 分支的 ID | #### Example ```text https://qr.expo.dev/eas-update?projectId=your-project-id&branchId=your-branch-id ``` ### Update by channel ID 你可以使用频道的 ID 创建一个 QR 码,它将返回映射到该频道的分支上的最新可用更新。 | Param | Required | Description | | --- | --- | --- | | `projectId` | Yes | 项目的 ID | | `channelId` | Yes | 频道的 ID | #### Example ```text https://qr.expo.dev/eas-update?projectId=your-project-id&channelId=your-channel-id ``` --- --- title: 发布状态 description: 了解 alpha、preview、beta 和 stable 发布状态,以及它们在使用 Expo SDK 和 Expo Application Services(EAS)时如何影响功能稳定性。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/more/release-statuses/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # 发布状态 了解 alpha、preview、beta 和 stable 发布状态,以及它们在使用 Expo SDK 和 Expo Application Services(EAS)时如何影响功能稳定性。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. Expo 使用不同的发布状态来表示其工具和服务的稳定性与就绪程度。了解这些状态可以帮助你在项目中就要使用哪些功能和版本做出更明智的决定。 ## Alpha Alpha 功能可供早期测试,但可能存在较大的限制。这些功能处于开发的最早阶段,会与社区分享以收集反馈并塑造其发展方向。 **可以预期:** - API 可能会在不提升主版本号的情况下发生破坏性变更 - 实现可能会根据反馈发生重大变化 - 可能存在已知错误或性能问题 - 不建议用于生产应用 Alpha 功能是影响 Expo 未来的机会。我们鼓励你在开发环境中测试这些功能,并[提供反馈](https://expo.dev/contact),帮助我们在它们面向更广泛的受众之前进一步完善。 ## Preview Preview 功能提供新功能的一部分的早期预览。与 alpha 版本不同,preview 功能以最小开销和有限范围为设计目标,但它们尚未功能完备。 **可以预期:** - 只涵盖一部分聚焦的功能,而非完整功能集 - 以最小开销设计,但尚未针对所有生产场景进行充分验证 - 随着功能进一步完善,API 可能会演进 - 可在生产环境中使用,但需要经过充分测试,不过功能有限 preview 的目的是尽早分享新功能,并在进一步完善之前收集关于特定部分的反馈。你的意见将直接帮助塑造该功能的方向。[分享你的反馈](https://expo.dev/contact),帮助我们确定下一步优先构建什么。 ## Beta Beta 功能已经功能完备,正在进行最终验证。这些功能的核心能力已经实现,正为稳定发布做准备。 **可以预期:** - 核心功能已完成,API 形态大体已定 - 可能存在正在处理的小错误或边缘情况 - 可能发生破坏性变更,但除非发现严重问题,否则可能性不大 - 可在生产环境中使用,但需要经过充分测试 Beta 功能已准备好用于真实世界测试。虽然我们不预期会有重大变更,但如果你计划在生产环境中使用,我们建议进行彻底测试。[你的反馈](https://expo.dev/contact)在这个阶段能帮助我们在稳定发布前发现任何遗留问题。 ## Stable 没有任何状态徽章的功能被视为 stable,并已完全发布,可用于生产环境。这些功能已经过充分测试,并遵循语义化版本控制来处理未来的任何变更。 **可以预期:** - 可直接用于生产,并获得完整支持 - 破坏性变更只会在主版本发布时发生 - 性能和稳定性已经过验证 - 提供文档和示例 Stable 功能已准备好可用于任何应用。你可以依赖它们遵循语义化版本控制原则,这意味着破坏性变更只会在主版本更新中发生。 ## Deprecated Deprecated 功能是不再建议使用、并将在未来版本中移除的功能。我们会提供弃用警告,给开发者时间从这些功能迁移出去。 **可以预期:** - 在使用 deprecated 功能时,文档和代码中会出现警告 - 不会再新增功能或改进 - 将在未来的主版本中移除 当你遇到一个 deprecated 功能时,我们建议尽快规划迁移到建议的替代方案,以确保你的项目保持最新并易于维护。 --- --- modificationDate: 2021 年 5 月 24 日 title: Expo 结构化字段值 description: 版本 0 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/technical-specs/expo-sfv-0/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # Expo 结构化字段值 版本 0 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. HTTP 的结构化字段值,[IETF RFC 8941](https://tools.ietf.org/html/rfc8941),是一项旨在规范标头语法并促进嵌套数据的提案。 由于它仍处于进行中状态,Expo 维护了一个自定义版本,仅实现了 [IETF RFC 8941](https://tools.ietf.org/html/rfc8941) 中定义的协议的以下子集: - 所有键值 - 字符串、整数和小数项 - 字典 --- --- modificationDate: March 13, 2023 title: Expo Updates v1 description: 版本 1 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/technical-specs/expo-updates-1/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # Expo Updates v1 版本 1 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. ## 介绍 这是 Expo Updates 的规范,它是一个用于向运行在多个平台上的 Expo 应用交付更新的协议。 ### 一致性 符合规范的服务器和客户端库必须满足所有规范性要求。本文档通过描述性断言和具有明确定义含义的关键词来描述一致性要求。 本文档规范性部分中的关键词 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY” 和 “OPTIONAL” 应按照 [IETF RFC 2119](https://tools.ietf.org/html/rfc2119) 中的描述进行解释。这些关键词可以以小写形式出现,但除非明确声明为非规范性,否则仍保留其含义。 该协议的符合规范实现 MAY 提供额外功能,但在明确禁止的地方或会导致不符合规范的情况下 MUST NOT 提供额外功能。凡相关之处,符合规范的客户端应允许并忽略未知字段。 ### 概述 符合规范的服务器和客户端库 MUST 遵循 [RFC 7231](https://tools.ietf.org/html/rfc7231) 中描述的 HTTP 规范,以及本规范中更精确的指导。 - _update_ 定义为一个 [_manifest_](/technical-specs/expo-updates-1#manifest-body) 以及 manifest 内引用的资源。 - [_directive_](/technical-specs/expo-updates-1#directive-body) 定义为来自服务器的一条消息,用于指示客户端执行某个操作。 Expo Updates 是一种用于向客户端组装并交付更新和指令的协议。 本规范的主要受众是 Expo Application Services,以及希望管理自己的更新服务器以满足内部需求的组织。 ## 客户端 > 参见 [参考客户端库](https://github.com/expo/expo/tree/main/packages/expo-updates)。 运行符合规范的 Expo Updates 客户端库的应用 MUST 加载保存在客户端库更新数据库中的最新 _update_,并可能根据更新 manifest 的 [_metadata_](/technical-specs/expo-updates-1#manifest-body) 内容进行过滤。 以下内容描述了符合规范的 Expo Updates 客户端库 MUST 如何从符合规范的服务器获取新更新: 1. 客户端库 MUST 发起一个针对最新更新和指令的 [请求](/technical-specs/expo-updates-1#request),并在请求头中指定约束条件。 2. 如果收到了一个 [响应](/technical-specs/expo-updates-1#response),客户端库 MUST 处理其内容: - 对于包含 _update_ 的响应,客户端库 SHALL 继续发起额外请求,下载并存储 manifest 中指定的任何新资源。manifest 和资源一起被视为一个新的 _update_。客户端库将编辑其本地状态,以反映新的 update 已被添加到本地存储中。它还会使用响应 [headers](/technical-specs/expo-updates-1#manifest-response-headers) 中找到的新 `expo-manifest-filters` 和 `expo-server-defined-headers` 更新本地状态。 - 对于包含 _directive_ 的响应,客户端库将根据指令类型消费该指令,并相应地编辑其本地状态。 ## 请求 符合规范的客户端库 MUST 使用以下请求头发起 GET 请求: 1. `expo-protocol-version: 1`,用于指定本 Expo Updates 规范的第 1 版。 2. `expo-platform`,用于指定客户端运行的平台类型。 - iOS MUST 为 `expo-platform: ios`。 - Android MUST 为 `expo-platform: android`。 - 如果不是这些平台之一,服务器 SHOULD 返回 400 或 404 3. `expo-runtime-version` MUST 是与客户端兼容的运行时版本。运行时版本规定了客户端所运行的原生代码配置。它应在客户端构建时设置。例如,在 iOS 客户端中,该值可以设置在 plist 文件中。 4. 任何前一个响应的 [server defined headers](/technical-specs/expo-updates-1#response) 所规定的请求头。 符合规范的客户端库 MAY 基于 [支持的响应结构](/technical-specs/expo-updates-1#response) 发送 `accept: application/expo+json`、`accept: application/json` 或 `accept: multipart/mixed` 之一,尽管它 SHOULD 发送 `accept: application/expo+json, application/json, multipart/mixed`。符合规范的客户端库 MAY 按照 [RFC 7231](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.1) 的规定使用 "q" 参数表达偏好,其默认值为 `1`。 配置为执行 [code signing](/technical-specs/expo-updates-1#code-signing) 验证的符合规范的客户端库 MUST 发送 `expo-expect-signature` 请求头,以表明它期望符合规范的服务器在 manifest 响应中包含 `expo-signature` 请求头。`expo-expect-signature` 是一个 [Expo SFV](/technical-specs/expo-sfv-0) 字典,其中 MAY 包含以下任意键值对: - `sig` SHOULD 包含布尔值 `true`,以表明它要求符合规范的服务器在 `sig` 键中返回签名。 - `keyid` SHOULD 包含客户端将用于验证签名的公钥的 keyId - `alg` SHOULD 包含客户端将用于验证签名的算法 示例: ```text expo-protocol-version: 1 accept: application/expo+json;q=0.9, application/json;q=0.8, multipart/mixed expo-platform: * expo-runtime-version: * expo-expect-signature: sig, keyid="root", alg="rsa-v1_5-sha256" ``` ## 响应 符合规范的服务器 MUST 返回至少符合以下两种响应结构之一的响应,MAY 支持其中一种或两种响应结构;当请求了不受支持的响应结构时,服务器 SHOULD 返回 HTTP `406` 错误状态。如果服务器希望针对所请求的协议版本返回不兼容的响应,也 SHOULD 改为返回 HTTP `406` 错误状态。 - 对于 `content-type: application/json` 或 `content-type: application/expo+json` 的响应,[common response headers](/technical-specs/expo-updates-1#common-response-headers) 和 [other response headers](/technical-specs/expo-updates-1#other-response-headers) MUST 在响应头中发送,而 [manifest body](/technical-specs/expo-updates-1#manifest-body) MUST 在响应体中发送。此响应格式不支持多个响应部分,因此不支持 _directives_;当要提供的最新响应不是 _update_ 时,SHOULD 返回 HTTP `406` 错误状态。 - 对于 `content-type: multipart/mixed` 的响应,响应 MUST 按照 [multipart response](/technical-specs/expo-updates-1#multipart-response) 部分中的规定进行结构化。 - 没有任何部分的 [multipart response](/technical-specs/expo-updates-1#multipart-response) MAY 返回 HTTP `204` 状态且无内容,因此也没有 `content-type` 响应头。 update 和 headers 的选择取决于请求头的值。符合规范的服务器 MUST 返回按创建时间排序、满足 [request headers](/technical-specs/expo-updates-1#request) 所施加的所有参数和约束的最新 update。服务器 MAY 使用请求的任何属性,如其 headers 和源 IP 地址,在多个都满足请求约束的更新之间进行选择。 ### 通用响应头 ```text expo-protocol-version: 1 expo-sfv-version: 0 expo-manifest-filters: expo-server-defined-headers: cache-control: * content-type: * ``` - `expo-protocol-version` 描述了本规范中定义的协议版本,且 MUST 为 `1`。 - `expo-sfv-version` MUST 为 `0`。 - `expo-manifest-filters` 是一个 [Expo SFV](/technical-specs/expo-sfv-0) 字典。它用于根据 [manifest](/technical-specs/expo-updates-1#manifest-body) 中 `metadata` 属性的值,过滤客户端库存储的更新。如果筛选器中提到了某个字段,则相应 metadata 字段必须缺失或相等,更新才会被包含。客户端库 MUST 存储 manifest filters,直到它被更新的响应覆盖。 - `expo-server-defined-headers` 是一个 [Expo SFV](/technical-specs/expo-sfv-0) 字典。它定义了客户端库 MUST 存储的请求头,直到被更新的字典覆盖,并且它们 MUST 包含在之后每次 [update request](/technical-specs/expo-updates-1#request) 中。 - `cache-control` MUST 设置为一个足够短的时间段。建议使用 `cache-control: private, max-age=0`,以确保返回最新 manifest。设置更长的缓存时间可能导致返回过期更新。 - `content-type` MUST 通过 [RFC 7231](https://tools.ietf.org/html/rfc7231#section-3.4.1) 中定义的 _proactive negotiation_ 决定。由于客户端库 [要求](/technical-specs/expo-updates-1#request) 在每次 manifest 请求中发送 `accept` 请求头,因此这里总是会是 `application/expo+json`、`application/json`;否则请求将返回 `406` 错误。 ### 其他响应头 ```text expo-signature: * ``` - `expo-signature` SHOULD 包含 manifest 的签名,以便在 [code signing](/technical-specs/expo-updates-1#code-signing) 的验证步骤中使用,前提是对 manifest 的请求包含了 `expo-expect-signature` 请求头。这是一个 [Expo SFV](/technical-specs/expo-sfv-0) 字典,其中 MAY 包含以下任意键值对: - `sig` MUST 包含 manifest 的签名。此字段的名称与 `expo-expect-signature` 一致。 - `keyid` MAY 包含服务器用于对响应签名的密钥的 keyId。客户端 SHOULD 使用与此 `keyid` 匹配的证书来验证签名。 - `alg` MAY 包含服务器用于对响应签名的算法。客户端 SHOULD 仅在其与 `keyid` 所匹配证书定义的算法一致时使用此字段。 ### 多部分响应 这种格式的更新响应由 [RFC 2046](https://tools.ietf.org/html/rfc2046#section-5.1) 中定义的 `multipart/mixed` MIME 类型定义。 此响应格式的头部是 [common response headers](/technical-specs/expo-updates-1#common-response-headers),但有以下例外: - `content-type` SHOULD 具有 [RFC 2046](https://tools.ietf.org/html/rfc2046#section-5.1) 中定义的 `multipart/mixed` 值 部分的顺序不受严格限制。没有任何部分(零长度 body)的多部分响应应被视为无操作(没有可用的更新或指令),不过响应头 SHOULD 仍然发送,并由客户端处理。 每个部分定义如下: 1. 可选的 `"manifest"` 部分: - MUST 具有分部头 `content-disposition: form-data; name="manifest"`。第一个参数(`form-data`)不一定需要是 `form-data`,但 `name` 参数必须取值为 `manifest`。 - MUST 具有分部头 `content-type: application/json` 或 `application/expo+json`。 - 如果正在使用 code signing,则 SHOULD 具有 [other response headers](/technical-specs/expo-updates-1#other-response-headers) 中定义的分部头 `expo-signature`。 - [manifest body](/technical-specs/expo-updates-1#manifest-body) MUST 作为分部内容发送。 2. 可选的 `"extensions"` 部分: - MUST 具有分部头 `content-disposition: form-data; name="extensions"`。第一个参数(`form-data`)不一定需要是 `form-data`,但 `name` 参数必须取值为 `extensions`。 - MUST 具有分部头 `content-type: application/json`。 - [extensions-body](/technical-specs/expo-updates-1#extensions-body) MUST 作为分部内容发送。 3. 可选的 `"directive"` 部分: - MUST 具有分部头 `content-disposition: form-data; name="directive"`。第一个参数(`form-data`)不一定需要是 `form-data`,但 `name` 参数必须取值为 `directive`。 - MUST 具有分部头 `content-type: application/json` 或 `application/expo+json`。 - 如果正在使用 code signing,则 SHOULD 具有 [other response headers](/technical-specs/expo-updates-1#other-response-headers) 中定义的分部头 `expo-signature`。 - [directive body](/technical-specs/expo-updates-1#directive-body) MUST 作为分部内容发送。 ### Manifest body 定义为符合以下以 [TypeScript](https://www.typescriptlang.org/) 表示的 `Manifest` 定义以及每个字段详细说明的 JSON: ```ts type Manifest = { id: string; createdAt: string; runtimeVersion: string; launchAsset: Asset; assets: Asset[]; metadata: { [key: string]: string }; extra: { [key: string]: any }; }; type Asset = { hash?: string; key: string; contentType: string; fileExtension?: string; url: string; }; ``` - `id`:该 ID MUST 唯一标识该 manifest,并且 MUST 是一个 UUID。 - `createdAt`:创建该更新的日期和时间至关重要,因为客户端库会选择最新的更新(受 `expo-manifest-filters` 请求头提供的任何约束影响)。该 datetime 应按照 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) 格式化。 - `runtimeVersion`:可以是开发者定义的任意字符串。它规定了运行相关更新所需的原生代码配置。 - `launchAsset`:作为应用代码入口点的特殊资源。该资源会忽略 `fileExtension` 字段,并 SHOULD 省略。 - `assets`:更新 bundle 使用的资源数组,例如 JavaScript、图片和字体。在执行更新之前,所有资源(包括 `launchAsset`)都应下载到磁盘,并且应向应用代码提供 asset `key` 到磁盘位置的映射。 - 每个 asset 对象的属性: - `hash`:文件的 Base64URL 编码 SHA-256 哈希,用于保证完整性。Base64URL 编码由 [IETF RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648#section-5) 定义。 - `key`:用于在更新的应用代码中引用此资源的键。例如,该键可由处理应用代码的单独构建步骤生成,例如打包器。 - `contentType`:文件的 MIME 类型,由 [RFC 2045](https://tools.ietf.org/html/rfc2045) 定义。例如 `application/javascript`、`image/jpeg`。 - `fileExtension`:在客户端保存文件时建议使用的扩展名。某些平台(如 iOS)要求某些文件类型必须带扩展名保存。扩展名 MUST 以前缀 `.` 开头。例如,**.jpeg**。在某些情况下,例如 launchAsset,此字段会被本地确定的扩展名所取代而忽略。如果该字段被省略且没有本地规定的扩展名,则资源将不带扩展名保存。例如,`./filename` 末尾没有 `.`。 符合规范的客户端 SHOULD 在文件扩展名非空但缺少 `.` 前缀时,为其添加 `.` 前缀。 - `url`:文件可获取的位置。 - `metadata`:与更新相关联的元数据。它是一个以字符串为值的字典。服务器 MAY 返回它希望用于过滤更新的任何内容。metadata MUST 满足随附的 `expo-manifest-filters` 请求头定义的过滤条件。 - `extra`:用于存储可选的 “extra” 信息,例如第三方配置。例如,如果更新托管在 Expo Application Services (EAS) 上,则可以包含 EAS 项目 ID: ```json "extra": { "eas": { "projectId": "00000000-0000-0000-0000-000000000000" } } ``` ### 扩展 body 定义为符合以下以 [TypeScript](https://www.typescriptlang.org/) 表示的 `Extensions` 定义以及每个字段详细说明的 JSON: ```ts type Extensions = { assetRequestHeaders: ExpoAssetHeaderDictionary; ... } type ExpoAssetHeaderDictionary = { [assetKey: string]: { [headerName: string]: string, }; } ``` - `assetRequestHeaders`:MAY 包含一个头(key、value)对的字典,用于与资源请求一起发送。Key 和 value MUST 都是字符串。 ### 指令 body 定义为符合以下以 [TypeScript](https://www.typescriptlang.org/) 表示的 `Directive` 定义以及每个字段详细说明的 JSON: ```ts type Directive = { type: string; parameters?: { [key: string]: any }; extra?: { [key: string]: any }; }; ``` - `type`:指令的类型。 - `parameters`:MAY 包含任何与 `type` 相关的附加信息。 - `extra`:用于存储可选的 “extra” 信息,例如第三方信息。例如,如果更新托管在 Expo Application Services (EAS) 上,则可以包含 EAS 项目 ID。 符合规范的客户端库和服务器 MAY 指定并实现适用于应用需求的特定指令类型。例如,到目前为止,Expo Application Services 使用了一种类型:`rollBackToEmbedded`,它指示 expo-updates 库使用宿主应用中嵌入的更新,而不是任何其他已下载的更新。 ## 资源请求 符合规范的客户端库 MUST 对清单中指定的资源 URL 发起 GET 请求。客户端库 SHOULD 包含一个接受清单中指定的资源内容类型的标头。此外,客户端库 SHOULD 指定客户端库能够处理的压缩编码。 示例标头: ```text accept: image/jpeg, */* accept-encoding: br, gzip ``` 符合规范的客户端库 MUST 还要为此资源键包含 [`assetRequestHeaders`](/technical-specs/expo-updates-1#manifest-extensions) 中包含的任何标头(键、值)对。 ## 资源响应 位于特定 URL 的资源 MUST NOT 自创建以来被更改或移除,因为客户端库可能会在任何更新时随时获取资源。符合规范的客户端 MUST 验证资源的 base64url 编码 SHA-256 哈希与清单中该资源的 `hash` 字段匹配。 ### 资源响应标头 资源 MUST 使用客户端根据请求的 `accept-encoding` 标头所支持的压缩格式进行编码。服务器 MAY 提供未压缩的资源。响应 MUST 包含一个 `content-type` 标头,其中包含该资源的 MIME 类型。 例如: ```text content-encoding: br content-type: application/javascript ``` 建议为资源提供 `cache-control` 标头,并将其设置为较长的持续时间,因为位于给定 URL 的资源不得更改。例如: ```text cache-control: public, max-age=31536000, immutable ``` ### 压缩 资源 SHOULD 能够以 [Gzip](https://www.gnu.org/software/gzip/) 和 [Brotli](https://github.com/google/brotli) 压缩方式提供。 ## 代码签名 Expo Updates 支持对清单和指令正文进行代码签名。对清单进行代码签名也会连带对资源进行签名,因为资源的哈希值存在于清单中,并会由符合规范的客户端进行验证。符合规范的客户端 MAY 使用私钥请求对清单或指令进行签名,然后在使用之前或在下载任何相应的清单资源之前,MUST 使用相应的代码签名证书验证清单或指令的签名。客户端 MUST 验证签名证书要么是自签名的受信任根证书,要么是由受信任根证书签名的证书链中的一部分。在任一情况下,根证书 MUST 嵌入在应用程序或设备的操作系统中。 --- --- title: app.json / app.config.js description: Expo 应用配置中可用属性的参考。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/versions/latest/config/app/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # app.json / app.config.js Expo 应用配置中可用属性的参考。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. 以下是在 **app.json** 或 **app.config.json** 中 `"expo"` 键下可用的属性列表。这些属性也可以传递给 **app.config.js** 或 **app.config.ts** 的顶层对象。 [使用 app 配置进行配置](/workflow/configuration) — 有关应用配置、各种 app 配置文件之间的差异,以及如何动态使用它们的信息。 ## 属性 ### `name` Type: `string` The name of your app as it appears both within Expo Go and on your home screen as a standalone app. Existing React Native app? To change the name of your app, edit the 'Display Name' field in Xcode and the `app_name` string in `android/app/src/main/res/values/strings.xml` ### `description` Type: `string` A short description of what your app is and why it is great. ### `slug` Type: `string` A URL-friendly name for your project that is unique across your account. ### `owner` Type: `string` The name of the Expo account that owns the project. This is useful for teams collaborating on a project. If not provided, the owner defaults to the username of the current user. ### `currentFullName` Type: `string` The auto generated Expo account name and slug used for display purposes. It is not meant to be set directly. Formatted like `@username/slug`. When unauthenticated, the username is `@anonymous`. For published projects, this value may change when a project is transferred between accounts or renamed. ### `originalFullName` Type: `string` The auto generated Expo account name and slug used for services like Notifications and AuthSession proxy. It is not meant to be set directly. Formatted like `@username/slug`. When unauthenticated, the username is `@anonymous`. For published projects, this value will not change when a project is transferred between accounts or renamed. ### `sdkVersion` Type: `string` The Expo sdkVersion to run the project on. This should line up with the version specified in your package.json. ### `runtimeVersion` One of types: - `string` matching the following pattern: `^[a-zA-Z\d][a-zA-Z\d._+()-]{0,254}$` - `string` matching the following pattern: `^exposdk:((\d+\.\d+\.\d+)|(UNVERSIONED))$` - An `object` with the following properties: #### `policy` Type: `enum` • Path: `runtimeVersion.policy` Valid values: `nativeVersion`, `sdkVersion`, `appVersion`, `fingerprint`. Property indicating compatibility between a build's native code and an OTA update. ### `version` Type: `string` Your app version. In addition to this field, you'll also use `ios.buildNumber` and `android.versionCode` — read more about how to version your app [here](https://docs.expo.dev/distribution/app-stores/#versioning-your-app). On iOS this corresponds to `CFBundleShortVersionString`, and on Android, this corresponds to `versionName`. The required format can be found [here](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring). Existing React Native app? To change your app version, edit the 'Version' field in Xcode and the `versionName` string in `android/app/build.gradle` ### `platforms` Type: `array` Platforms that your project explicitly supports. If not specified, it defaults to `["ios", "android"]`. If `react-dom` is installed, `web` is also included by default. Example `[ "ios", "android", "web" ]` ### `githubUrl` Type: `string` If you would like to share the source code of your app on Github, enter the URL for the repository here and it will be linked to from your Expo project page. Example `"https://github.com/expo/expo"` ### `orientation` Type: `enum` • One of: `default`, `portrait`, `landscape` Locks your app to a specific orientation with portrait or landscape. Defaults to no lock. Valid values: `default`, `portrait`, `landscape` ### `userInterfaceStyle` Type: `enum` • One of: `light`, `dark`, `automatic` Configuration to force the app to always use the light or dark user-interface appearance, such as "dark mode", or make it automatically adapt to the system preferences. If not provided, defaults to `light`. Requires `expo-system-ui` be installed in your project to work on Android. ### `backgroundColor` Type: `string` The background color for your app, behind any of your React views. This is also known as the root view background color. Requires `expo-system-ui` be installed in your project to work on iOS. 6 character long hex color string, for example, `'#000000'`. Default is white: `'#ffffff'` ### `primaryColor` Type: `string` On Android, this will determine the color of your app in the multitasker. Currently this is not used on iOS, but it may be used for other purposes in the future. 6 character long hex color string, for example, `'#000000'` ### `icon` Type: `string` Local path or remote URL to an image to use for your app's icon. We recommend that you use a 1024x1024 png file. This icon will appear on the home screen and within the Expo Go app. Existing React Native app? To change your app's icon, edit or replace the files in `ios//Assets.xcassets/AppIcon.appiconset` (we recommend using Xcode), and `android/app/src/main/res/mipmap-`. Be sure to follow the guidelines for each platform ([iOS](https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/app-icon/), [Android 7.1 and below](https://material.io/design/iconography/#icon-treatments), and [Android 8+](https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive)) and to provide your new icon in each existing size. ### `androidStatusBar` Type: `object` Configuration for the status bar on Android. For more details navigate to [Configuring StatusBar](https://docs.expo.dev/guides/configuring-statusbar/). #### `barStyle` Type: `enum` • One of: `light-content`, `dark-content` • Path: `androidStatusBar.barStyle` Configures the status bar icons to have a light or dark color. Valid values: `light-content`, `dark-content`. Defaults to `dark-content` #### `backgroundColor` Type: `string` • Path: `androidStatusBar.backgroundColor` Specifies the background color of the status bar. Defaults to `#00000000` (transparent) for `dark-content` bar style and `#00000088` (semi-transparent black) for `light-content` bar style 6 character long hex color string `'#RRGGBB'`, for example, `'#000000'` for black. Or 8 character long hex color string `'#RRGGBBAA'`, for example, `'#00000088'` for semi-transparent black. #### `hidden` Type: `boolean` • Path: `androidStatusBar.hidden` Instructs the system whether the status bar should be visible or not. Defaults to `false` #### `translucent` Type: `boolean` • Path: `androidStatusBar.translucent` When false, the system status bar pushes the content of your app down (similar to `position: relative`). When true, the status bar floats above the content in your app (similar to `position: absolute`). Defaults to `true` to match the iOS status bar behavior (which can only float above content). Explicitly setting this property to `true` will add `android:windowTranslucentStatus` to `styles.xml` and may cause unexpected keyboard behavior on Android when using the `softwareKeyboardLayoutMode` set to `resize`. In this case you will have to use `KeyboardAvoidingView` to manage the keyboard layout. ### `developmentClient` Type: `object` Settings that apply specifically to running this app in a development client #### `silentLaunch` Type: `boolean` • Path: `developmentClient.silentLaunch` If true, the app will launch in a development client with no additional dialogs or progress indicators, just like in a standalone app. ### `scheme` One of types: - `string` matching the following pattern: `^[a-z][a-z0-9+.-]*$` `{ "type": "array", "items": { "type": "string", "pattern": "^[a-z][a-z0-9+.-]*$" } }` URL scheme(s) to link into your app. For example, if we set this to `'demo'`, then demo:// URLs would open your app when tapped. This is a build-time configuration, it has no effect in Expo Go. String beginning with a **lowercase** letter followed by any combination of **lowercase** letters, digits, "+", "." or "-" Existing React Native app? To change your app's scheme, replace all occurrences of the old scheme in `Info.plist` and `AndroidManifest.xml` ### `extra` Type: `object` Any extra fields you want to pass to your experience. Values are accessible via `Constants.expoConfig.extra` ([Learn more](https://docs.expo.dev/versions/latest/sdk/constants/#constantsmanifest)) ### `updates` Type: `object` Configuration for the expo-updates library #### `enabled` Type: `boolean` • Path: `updates.enabled` Whether the updates system will run. Defaults to true. If set to false, builds will only use code and assets bundled at time of build. #### `checkAutomatically` Type: `enum` • One of: `ON_ERROR_RECOVERY`, `ON_LOAD`, `WIFI_ONLY`, `NEVER` • Path: `updates.checkAutomatically` By default, expo-updates will check for updates every time the app is loaded. Set this to `ON_ERROR_RECOVERY` to disable automatic checking unless recovering from an error. Set this to `NEVER` to disable automatic checking. Valid values: `ON_LOAD` (default value), `ON_ERROR_RECOVERY`, `WIFI_ONLY`, `NEVER` #### `useEmbeddedUpdate` Type: `boolean` • Path: `updates.useEmbeddedUpdate` Whether to load the embedded update. Defaults to true. If set to false, an update will be fetched at launch. When set to false, ensure that `checkAutomatically` is set to `ON_LOAD` and `fallbackToCacheTimeout` is large enough for the initial remote update to download. This should not be used in production. #### `fallbackToCacheTimeout` Type: `number` • Path: `updates.fallbackToCacheTimeout` How long (in ms) to wait for the app to check for and fetch a new update upon launch before falling back to the most recent update already present on the device. Defaults to 0. Must be between 0 and 300000 (5 minutes). If the startup update check takes longer than this value, any update downloaded during the check will be applied upon the next app launch. #### `url` Type: `string` • Path: `updates.url` URL from which expo-updates will fetch update manifests #### `codeSigningCertificate` Type: `string` • Path: `updates.codeSigningCertificate` Local path of a PEM-formatted X.509 certificate used for verifying codesigned updates. When provided, all updates downloaded by expo-updates must be signed. #### `codeSigningMetadata` Type: `object` • Path: `updates.codeSigningMetadata` Metadata for `codeSigningCertificate` ##### `alg` Type: `enum` • One of: `rsa-v1_5-sha256` • Path: `updates.codeSigningMetadata.alg` Algorithm used to generate manifest code signing signature. Valid values: `rsa-v1_5-sha256` ##### `keyid` Type: `string` • Path: `updates.codeSigningMetadata.keyid` Identifier for the key in the certificate. Used to instruct signing mechanisms when signing or verifying signatures. #### `requestHeaders` Type: `object` • Path: `updates.requestHeaders` Extra HTTP headers to include in HTTP requests made by `expo-updates` when fetching manifests or assets. These may override preset headers. #### `assetPatternsToBeBundled` Type: `array` • Path: `updates.assetPatternsToBeBundled` Array of glob patterns specifying which files should be included in updates. Glob patterns are relative to the project root. A value of `['**']` will match all asset files within the project root. When not supplied all asset files will be included. Example: Given a value of `['app/images/**/*.png', 'app/fonts/**/*.woff']` all `.png` files in all subdirectories of `app/images` and all `.woff` files in all subdirectories of `app/fonts` will be included in updates. #### `disableAntiBrickingMeasures` Type: `boolean` • Path: `updates.disableAntiBrickingMeasures` Whether to disable the built-in expo-updates anti-bricking measures. Defaults to false. If set to true, this will allow overriding certain configuration options from the JS API, which is liable to leave an app in a bricked state if not done carefully. This should not be used in production. #### `useNativeDebug` Type: `boolean` • Path: `updates.useNativeDebug` Enable debugging of native code with updates enabled. Defaults to false. If set to true, the EX_UPDATES_NATIVE_DEBUG environment variable will be set in Podfile.properties.json and gradle.properties. This causes Xcode and Android Studio debug builds to be built with expo-updates enabled, and JS debugging (with dev client or packager) disabled. This should not be used in production. #### `enableBsdiffPatchSupport` Type: `boolean` • Path: `updates.enableBsdiffPatchSupport` Whether to enable support for downloading and applying bundle diffs using bsdiff. Defaults to false. ### `locales` Type: `object` Provide per-locale values for System Dialog prompts such as Permissions Boxes, and create Localizable.strings file to localize (for example) push notifications. Platform-specific locale strings should be nested under `ios` and `android` keys. Existing React Native app? To add or change language and localization information in your iOS app, you need to use Xcode. ### `plugins` Type: `array` Config plugins for adding extra functionality to your project. [Learn more](https://docs.expo.dev/guides/config-plugins/). Existing React Native app? Plugins that add modifications can only be used with [prebuilding](https://expo.fyi/prebuilding) and managed EAS Build ### `buildCacheProvider` Type: `undefined` Enable downloading cached builds from remote. ### `ios` Type: `object` Configuration that is specific to the iOS platform. #### `appleTeamId` Type: `string` • Path: `ios.appleTeamId` The Apple development team ID to use for all native targets. You can find your team ID in [the Apple Developer Portal](https://developer.apple.com/help/account/manage-your-team/locate-your-team-id/). #### `publishManifestPath` Type: `string` • Path: `ios.publishManifestPath` The manifest for the iOS version of your app will be written to this path during publish. #### `publishBundlePath` Type: `string` • Path: `ios.publishBundlePath` The bundle for the iOS version of your app will be written to this path during publish. #### `bundleIdentifier` Type: `string` • Path: `ios.bundleIdentifier` The bundle identifier for your iOS standalone app. You make it up, but it needs to be unique on the App Store. See [this StackOverflow question](http://stackoverflow.com/questions/11347470/what-does-bundle-identifier-mean-in-the-ios-project). iOS bundle identifier notation unique name for your app. For example, `host.exp.expo`, where `exp.host` is our domain and `expo` is our app name. Existing React Native app? Set this value in `info.plist` under `CFBundleIdentifier` #### `buildNumber` Type: `string` • Path: `ios.buildNumber` Build number for your iOS standalone app. Corresponds to `CFBundleVersion` and must match Apple's [specified format](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion). (Note: Transporter will pull the value for `Version Number` from `expo.version` and NOT from `expo.ios.buildNumber`.) Existing React Native app? Set this value in `info.plist` under `CFBundleVersion` #### `backgroundColor` Type: `string` • Path: `ios.backgroundColor` The background color for your iOS app, behind any of your React views. Overrides the top-level `backgroundColor` key if it is present. Requires `expo-system-ui` be installed in your project to work on iOS. 6 character long hex color string, for example, `'#000000'` #### `scheme` One of types: - `string` matching the following pattern: `^[a-z][a-z0-9+.-]*$` `{ "type": "array", "items": { "type": "string", "pattern": "^[a-z][a-z0-9+.-]*$" } }` URL scheme(s) to link into your iOS app. Schemes added to this field will be merged with the schemes in the `scheme` key at the top level of the config. String beginning with a **lowercase** letter followed by any combination of **lowercase** letters, digits, "+", "." or "-" Existing React Native app? To change your app's scheme, replace all occurrences of the old scheme in `Info.plist` and `AndroidManifest.xml` #### `icon` One of types: - `string` matching the following pattern: `\.icon$` - `string` - An `object` with the following properties: ##### `light` Type: `string` • Path: `ios.icon.light` The light icon. It will appear when neither dark nor tinted icons are used, or if they are not provided. ##### `dark` Type: `string` • Path: `ios.icon.dark` The dark icon. It will appear for the app when the user's system appearance is dark. See Apple's [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/app-icons#iOS-iPadOS) for more information. ##### `tinted` Type: `string` • Path: `ios.icon.tinted` The tinted icon. It will appear for the app when the user's system appearance is tinted. See Apple's [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/app-icons#iOS-iPadOS) for more information. Local path or remote URL to an image to use for your app's icon on iOS. Alternatively, an object specifying different icons for various system appearances (e.g., dark, tinted) can be provided. You can also provide a path to a .icon directory. If specified, this overrides the top-level `icon` key. Use a 1024x1024 icon which follows Apple's interface guidelines for icons, including color profile and transparency. Expo will generate the other required sizes. This icon will appear on the home screen and within the Expo Go app. #### `appStoreUrl` Type: `string` • Path: `ios.appStoreUrl` URL to your app on the Apple App Store, if you have deployed it there. This is used to link to your store page from your Expo project page if your app is public. Example `"https://apps.apple.com/us/app/expo-client/id982107779"` #### `bitcode` Type: `undefined` • Path: `ios.bitcode` Enable iOS Bitcode optimizations in the native build. Accepts the name of an iOS build configuration to enable for a single configuration and disable for all others, e.g. Debug, Release. Not available in Expo Go. Defaults to `undefined` which uses the template's predefined settings. #### `config` Type: `object` • Path: `ios.config` Note: This property key is not included in the production manifest and will evaluate to `undefined`. It is used internally only in the build process, because it contains API keys that some may want to keep private. ##### `branch` Type: `object` • Path: `ios.config.branch` [Branch](https://branch.io/) key to hook up Branch linking services. ##### `apiKey` Type: `string` • Path: `ios.config.branch.apiKey` Your Branch API key ##### `usesNonExemptEncryption` Type: `boolean` • Path: `ios.config.usesNonExemptEncryption` Sets `ITSAppUsesNonExemptEncryption` in the standalone ipa's Info.plist to the given boolean value. ##### `googleMapsApiKey` Type: `string` • Path: `ios.config.googleMapsApiKey` [Google Maps iOS SDK](https://developers.google.com/maps/documentation/ios-sdk/start) key for your standalone app. ##### `googleMobileAdsAppId` > Deprecated Type: `string` • Path: `ios.config.googleMobileAdsAppId` This field was used by the `expo-ads-admob` package, which has been deprecated and removed. [Google Mobile Ads App ID](https://support.google.com/admob/answer/6232340) Google AdMob App ID. ##### `googleMobileAdsAutoInit` > Deprecated Type: `boolean` • Path: `ios.config.googleMobileAdsAutoInit` This field was used by the `expo-ads-admob` package, which has been deprecated and removed. A boolean indicating whether to initialize Google App Measurement and begin sending user-level event data to Google immediately when the app starts. The default in Expo (Go and in standalone apps) is `false`. [Sets the opposite of the given value to the following key in `Info.plist`.](https://developers.google.com/admob/ios/eu-consent#delay_app_measurement_optional) #### `googleServicesFile` Type: `string` • Path: `ios.googleServicesFile` [Firebase Configuration File](https://support.google.com/firebase/answer/7015592) Location of the `GoogleService-Info.plist` file for configuring Firebase. #### `supportsTablet` Type: `boolean` • Path: `ios.supportsTablet` Whether your standalone iOS app supports tablet screen sizes. Defaults to `false`. Existing React Native app? Set this value in `info.plist` under `UISupportedInterfaceOrientations~ipad` #### `isTabletOnly` Type: `boolean` • Path: `ios.isTabletOnly` If true, indicates that your standalone iOS app does not support handsets, and only supports tablets. Existing React Native app? Set this value in `info.plist` under `UISupportedInterfaceOrientations` #### `requireFullScreen` Type: `boolean` • Path: `ios.requireFullScreen` If true, indicates that your standalone iOS app does not support Slide Over and Split View on iPad. Defaults to `false` Existing React Native app? Use Xcode to set `UIRequiresFullScreen` #### `userInterfaceStyle` Type: `enum` • One of: `light`, `dark`, `automatic` • Path: `ios.userInterfaceStyle` Configuration to force the app to always use the light or dark user-interface appearance, such as "dark mode", or make it automatically adapt to the system preferences. If not provided, defaults to `light`. #### `infoPlist` Type: `object` • Path: `ios.infoPlist` Dictionary of arbitrary configuration to add to your standalone app's native Info.plist. Applied prior to all other Expo-specific configuration. No other validation is performed, so use this at your own risk of rejection from the App Store. #### `entitlements` Type: `object` • Path: `ios.entitlements` Dictionary of arbitrary configuration to add to your standalone app's native \*.entitlements (plist). Applied prior to all other Expo-specific configuration. No other validation is performed, so use this at your own risk of rejection from the App Store. #### `privacyManifests` Type: `object` • Path: `ios.privacyManifests` Dictionary of privacy manifest definitions to add to your app's native PrivacyInfo.xcprivacy file. [Learn more](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files) ##### `NSPrivacyAccessedAPITypes` Type: `array` • Path: `ios.privacyManifests.NSPrivacyAccessedAPITypes` A list of required reasons of why your app uses restricted API categories. [Learn more](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api) ##### `NSPrivacyAccessedAPIType` Type: `string` • Path: `ios.privacyManifests.NSPrivacyAccessedAPITypes.NSPrivacyAccessedAPIType` A string that identifies the category of required reason APIs your app uses ##### `NSPrivacyAccessedAPITypeReasons` Type: `array` • Path: `ios.privacyManifests.NSPrivacyAccessedAPITypes.NSPrivacyAccessedAPITypeReasons` A list of reasons for a specific category. ##### `NSPrivacyTrackingDomains` Type: `array` • Path: `ios.privacyManifests.NSPrivacyTrackingDomains` A list of domains that your app uses for tracking. ##### `NSPrivacyTracking` Type: `boolean` • Path: `ios.privacyManifests.NSPrivacyTracking` A Boolean that indicates whether your app or third-party SDK uses data for tracking. ##### `NSPrivacyCollectedDataTypes` Type: `array` • Path: `ios.privacyManifests.NSPrivacyCollectedDataTypes` A list of collected data types that your app uses. ##### `NSPrivacyCollectedDataType` Type: `string` • Path: `ios.privacyManifests.NSPrivacyCollectedDataTypes.NSPrivacyCollectedDataType` ##### `NSPrivacyCollectedDataTypeLinked` Type: `boolean` • Path: `ios.privacyManifests.NSPrivacyCollectedDataTypes.NSPrivacyCollectedDataTypeLinked` ##### `NSPrivacyCollectedDataTypeTracking` Type: `boolean` • Path: `ios.privacyManifests.NSPrivacyCollectedDataTypes.NSPrivacyCollectedDataTypeTracking` ##### `NSPrivacyCollectedDataTypePurposes` Type: `array` • Path: `ios.privacyManifests.NSPrivacyCollectedDataTypes.NSPrivacyCollectedDataTypePurposes` #### `associatedDomains` Type: `array` • Path: `ios.associatedDomains` An array that contains Associated Domains for the standalone app. [Learn more](https://developer.apple.com/documentation/safariservices/supporting_associated_domains). Entries must follow the format `applinks:[:port number]`. [Learn more](https://developer.apple.com/documentation/safariservices/supporting_associated_domains). Existing React Native app? Build with EAS, or use Xcode to enable this capability manually. [Learn more](https://developer.apple.com/documentation/safariservices/supporting_associated_domains). #### `usesIcloudStorage` Type: `boolean` • Path: `ios.usesIcloudStorage` A boolean indicating if the app uses iCloud Storage for `DocumentPicker`. See `DocumentPicker` docs for details. Existing React Native app? Use Xcode, or ios.entitlements to configure this. #### `usesAppleSignIn` Type: `boolean` • Path: `ios.usesAppleSignIn` A boolean indicating if the app uses Apple Sign-In. See `AppleAuthentication` docs for details. #### `usesBroadcastPushNotifications` Type: `boolean` • Path: `ios.usesBroadcastPushNotifications` A boolean indicating if the app uses Push Notifications Broadcast option for Push Notifications capability. If true, EAS CLI will use the value during capability syncing. If EAS CLI is not used, this configuration will not have any effect unless another tool is used to operate on it, so enable the capability manually on the Apple Developer Portal in that case. #### `accessesContactNotes` Type: `boolean` • Path: `ios.accessesContactNotes` A Boolean value that indicates whether the app may access the notes stored in contacts. You must [receive permission from Apple](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_contacts_notes) before you can submit your app for review with this capability. #### `splash` > Deprecated Type: `object` • Path: `ios.splash` Use the `expo-splash-screen` config plugin instead. Configuration for loading and splash screen for standalone iOS apps. ##### `backgroundColor` Type: `string` • Path: `ios.splash.backgroundColor` Color to fill the loading screen background 6 character long hex color string, for example, `'#000000'` ##### `resizeMode` Type: `enum` • One of: `cover`, `contain` • Path: `ios.splash.resizeMode` Determines how the `image` will be displayed in the splash loading screen. Must be one of `cover` or `contain`, defaults to `contain`. ##### `image` Type: `string` • Path: `ios.splash.image` Local path or remote URL to an image to fill the background of the loading screen. Image size and aspect ratio are up to you. Must be a .png. ##### `tabletImage` Type: `string` • Path: `ios.splash.tabletImage` Local path or remote URL to an image to fill the background of the loading screen. Image size and aspect ratio are up to you. Must be a .png. ##### `dark` Type: `object` • Path: `ios.splash.dark` Configuration for loading and splash screen for standalone iOS apps in dark mode. ##### `backgroundColor` Type: `string` • Path: `ios.splash.dark.backgroundColor` Color to fill the loading screen background 6 character long hex color string, for example, `'#000000'` ##### `resizeMode` Type: `enum` • One of: `cover`, `contain` • Path: `ios.splash.dark.resizeMode` Determines how the `image` will be displayed in the splash loading screen. Must be one of `cover` or `contain`, defaults to `contain`. ##### `image` Type: `string` • Path: `ios.splash.dark.image` Local path or remote URL to an image to fill the background of the loading screen. Image size and aspect ratio are up to you. Must be a .png. ##### `tabletImage` Type: `string` • Path: `ios.splash.dark.tabletImage` Local path or remote URL to an image to fill the background of the loading screen. Image size and aspect ratio are up to you. Must be a .png. #### `runtimeVersion` One of types: - `string` matching the following pattern: `^[a-zA-Z\d][a-zA-Z\d._+()-]{0,254}$` - `string` matching the following pattern: `^exposdk:((\d+\.\d+\.\d+)|(UNVERSIONED))$` - An `object` with the following properties: ##### `policy` Type: `enum` • Path: `ios.runtimeVersion.policy` Valid values: `nativeVersion`, `sdkVersion`, `appVersion`, `fingerprint`. Property indicating compatibility between an iOS build's native code and an OTA update for the iOS platform. If provided, this will override the value of the top level `runtimeVersion` key on iOS. #### `version` Type: `string` • Path: `ios.version` Your iOS app version. Takes precedence over the root `version` field. In addition to this field, you'll also use `ios.buildNumber` — read more about how to version your app [here](https://docs.expo.dev/distribution/app-stores/#versioning-your-app). This corresponds to `CFBundleShortVersionString`. The required format can be found [here](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring). Existing React Native app? To change your app version, edit the 'Version' field in Xcode\` ### `android` Type: `object` Configuration that is specific to the Android platform. #### `publishManifestPath` Type: `string` • Path: `android.publishManifestPath` The manifest for the Android version of your app will be written to this path during publish. #### `publishBundlePath` Type: `string` • Path: `android.publishBundlePath` The bundle for the Android version of your app will be written to this path during publish. #### `package` Type: `string` • Path: `android.package` The package name for your Android standalone app. You make it up, but it needs to be unique on the Play Store. See [this StackOverflow question](http://stackoverflow.com/questions/6273892/android-package-name-convention). Reverse DNS notation unique name for your app. Valid Android Application ID. For example, `com.example.app`, where `com.example` is our domain and `app` is our app. The name may only contain lowercase and uppercase letters (a-z, A-Z), numbers (0-9) and underscores (_), separated by periods (.). Each component of the name should start with a lowercase letter. Existing React Native app? This is set in `android/app/build.gradle` as `applicationId` as well as in your `AndroidManifest.xml` file (multiple places). #### `versionCode` Type: `integer` • Path: `android.versionCode` Version number required by Google Play. Increment by one for each release. Must be a positive integer. [Learn more](https://developer.android.com/studio/publish/versioning.html) Existing React Native app? This is set in `android/app/build.gradle` as `versionCode` #### `backgroundColor` Type: `string` • Path: `android.backgroundColor` The background color for your Android app, behind any of your React views. Overrides the top-level `backgroundColor` key if it is present. 6 character long hex color string, for example, `'#000000'` Existing React Native app? This is set in `android/app/src/main/AndroidManifest.xml` under `android:windowBackground` #### `userInterfaceStyle` Type: `enum` • One of: `light`, `dark`, `automatic` • Path: `android.userInterfaceStyle` Configuration to force the app to always use the light or dark user-interface appearance, such as "dark mode", or make it automatically adapt to the system preferences. If not provided, defaults to `light`. Requires `expo-system-ui` be installed in your project to work on Android. #### `scheme` One of types: - `string` matching the following pattern: `^[a-z][a-z0-9+.-]*$` `{ "type": "array", "items": { "type": "string", "pattern": "^[a-z][a-z0-9+.-]*$" } }` URL scheme(s) to link into your Android app. Schemes added to this field will be merged with the schemes in the `scheme` key at the top level of the config. String beginning with a **lowercase** letter followed by any combination of **lowercase** letters, digits, "+", "." or "-" Existing React Native app? To change your app's scheme, replace all occurrences of the old scheme in `Info.plist` and `AndroidManifest.xml` #### `icon` Type: `string` • Path: `android.icon` Local path or remote URL to an image to use for your app's icon on Android. If specified, this overrides the top-level `icon` key. We recommend that you use a 1024x1024 png file (transparency is recommended for the Google Play Store). This icon will appear on the home screen and within the Expo Go app. #### `adaptiveIcon` Type: `object` • Path: `android.adaptiveIcon` Settings for an Adaptive Launcher Icon on Android. [Learn more](https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive) ##### `foregroundImage` Type: `string` • Path: `android.adaptiveIcon.foregroundImage` Local path or remote URL to an image to use for your app's icon on Android. If specified, this overrides the top-level `icon` and the `android.icon` keys. Should follow the [specified guidelines](https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive). This icon will appear on the home screen. ##### `monochromeImage` Type: `string` • Path: `android.adaptiveIcon.monochromeImage` Local path or remote URL to an image representing the Android 13+ monochromatic icon. Should follow the [specified guidelines](https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive). This icon will appear on the home screen when the user enables 'Themed icons' in system settings on a device running Android 13+. ##### `backgroundImage` Type: `string` • Path: `android.adaptiveIcon.backgroundImage` Local path or remote URL to a background image for your app's Adaptive Icon on Android. If specified, this overrides the `backgroundColor` key. Must have the same dimensions as `foregroundImage`, and has no effect if `foregroundImage` is not specified. Should follow the [specified guidelines](https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive). ##### `backgroundColor` Type: `string` • Path: `android.adaptiveIcon.backgroundColor` Color to use as the background for your app's Adaptive Icon on Android. Defaults to white, `#FFFFFF`. Has no effect if `foregroundImage` is not specified. 6 character long hex color string, for example, `'#000000'` #### `playStoreUrl` Type: `string` • Path: `android.playStoreUrl` URL to your app on the Google Play Store, if you have deployed it there. This is used to link to your store page from your Expo project page if your app is public. Example `"https://play.google.com/store/apps/details?id=host.exp.exponent"` #### `permissions` Type: `array` • Path: `android.permissions` A list of permissions to add to the app `AndroidManifest.xml` during prebuild. For example: `['android.permission.SCHEDULE_EXACT_ALARM']` Existing React Native app? To change the permissions your app requests, edit `AndroidManifest.xml` directly. To prevent your app from requesting specific permissions (which may automatically be added through an installed native package), add those permissions to `AndroidManifest.xml` along with a `tools:node="remove"` tag. #### `blockedPermissions` Type: `array` • Path: `android.blockedPermissions` List of permissions to block in the final `AndroidManifest.xml`. This is useful for removing permissions that are added by native package `AndroidManifest.xml` files which are merged into the final manifest. Internally this feature uses the `tools:node="remove"` XML attribute to remove permissions. Not available in Expo Go. #### `googleServicesFile` Type: `string` • Path: `android.googleServicesFile` [Firebase Configuration File](https://support.google.com/firebase/answer/7015592) Location of the `google-services.json` file for configuring Firebase. Including this key automatically enables FCM in your standalone app. Existing React Native app? Add or edit the file directly at `android/app/google-services.json` #### `config` Type: `object` • Path: `android.config` Note: This property key is not included in the production manifest and will evaluate to `undefined`. It is used internally only in the build process, because it contains API keys that some may want to keep private. ##### `branch` Type: `object` • Path: `android.config.branch` [Branch](https://branch.io/) key to hook up Branch linking services. ##### `apiKey` Type: `string` • Path: `android.config.branch.apiKey` Your Branch API key ##### `googleMaps` Type: `object` • Path: `android.config.googleMaps` [Google Maps Android SDK](https://developers.google.com/maps/documentation/android-api/signup) configuration for your standalone app. ##### `apiKey` Type: `string` • Path: `android.config.googleMaps.apiKey` Your Google Maps Android SDK API key ##### `googleMobileAdsAppId` > Deprecated Type: `string` • Path: `android.config.googleMobileAdsAppId` This field was used by the `expo-ads-admob` package, which has been deprecated and removed. [Google Mobile Ads App ID](https://support.google.com/admob/answer/6232340) Google AdMob App ID. ##### `googleMobileAdsAutoInit` > Deprecated Type: `boolean` • Path: `android.config.googleMobileAdsAutoInit` This field was used by the `expo-ads-admob` package, which has been deprecated and removed. A boolean indicating whether to initialize Google App Measurement and begin sending user-level event data to Google immediately when the app starts. The default in Expo (Client and in standalone apps) is `false`. [Sets the opposite of the given value to the following key in `Info.plist`](https://developers.google.com/admob/ios/eu-consent#delay_app_measurement_optional) #### `splash` > Deprecated Type: `object` • Path: `android.splash` Use the `expo-splash-screen` config plugin instead. Configuration for loading and splash screen for managed and standalone Android apps. ##### `backgroundColor` Type: `string` • Path: `android.splash.backgroundColor` Color to fill the loading screen background 6 character long hex color string, for example, `'#000000'` ##### `resizeMode` Type: `enum` • One of: `cover`, `contain`, `native` • Path: `android.splash.resizeMode` Determines how the `image` will be displayed in the splash loading screen. Must be one of `cover`, `contain` or `native`, defaults to `contain`. ##### `image` Type: `string` • Path: `android.splash.image` Local path or remote URL to an image to fill the background of the loading screen. Image size and aspect ratio are up to you. Must be a .png. ##### `mdpi` Type: `string` • Path: `android.splash.mdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Natural sized image (baseline)` ##### `hdpi` Type: `string` • Path: `android.splash.hdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Scale 1.5x` ##### `xhdpi` Type: `string` • Path: `android.splash.xhdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Scale 2x` ##### `xxhdpi` Type: `string` • Path: `android.splash.xxhdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Scale 3x` ##### `xxxhdpi` Type: `string` • Path: `android.splash.xxxhdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Scale 4x` ##### `dark` Type: `object` • Path: `android.splash.dark` Configuration for loading and splash screen for managed and standalone Android apps in dark mode. ##### `backgroundColor` Type: `string` • Path: `android.splash.dark.backgroundColor` Color to fill the loading screen background 6 character long hex color string, for example, `'#000000'` ##### `resizeMode` Type: `enum` • One of: `cover`, `contain`, `native` • Path: `android.splash.dark.resizeMode` Determines how the `image` will be displayed in the splash loading screen. Must be one of `cover`, `contain` or `native`, defaults to `contain`. ##### `image` Type: `string` • Path: `android.splash.dark.image` Local path or remote URL to an image to fill the background of the loading screen. Image size and aspect ratio are up to you. Must be a .png. ##### `mdpi` Type: `string` • Path: `android.splash.dark.mdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Natural sized image (baseline)` ##### `hdpi` Type: `string` • Path: `android.splash.dark.hdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Scale 1.5x` ##### `xhdpi` Type: `string` • Path: `android.splash.dark.xhdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Scale 2x` ##### `xxhdpi` Type: `string` • Path: `android.splash.dark.xxhdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Scale 3x` ##### `xxxhdpi` Type: `string` • Path: `android.splash.dark.xxxhdpi` Local path or remote URL to an image to fill the background of the loading screen in "native" mode. Image size and aspect ratio are up to you. [Learn more](https://developer.android.com/training/multiscreen/screendensities) `Scale 4x` #### `intentFilters` Type: `array` • Path: `android.intentFilters` Configuration for setting an array of custom intent filters in Android manifest. [Learn more](https://developer.android.com/guide/components/intents-filters) Existing React Native app? This is set in `AndroidManifest.xml` directly. [Learn more.](https://developer.android.com/guide/components/intents-filters) Example `[ { "autoVerify": true, "action": "VIEW", "data": { "scheme": "https", "host": "*.example.com" }, "category": [ "BROWSABLE", "DEFAULT" ] } ]` ##### `autoVerify` Type: `boolean` • Path: `android.intentFilters.autoVerify` You may also use an intent filter to set your app as the default handler for links (without showing the user a dialog with options). To do so use `true` and then configure your server to serve a JSON file verifying that you own the domain. [Learn more](https://developer.android.com/training/app-links) ##### `action` Type: `string` • Path: `android.intentFilters.action` ##### `data` Type: `undefined` • Path: `android.intentFilters.data` ##### `category` Type: `undefined` • Path: `android.intentFilters.category` #### `allowBackup` Type: `boolean` • Path: `android.allowBackup` Allows your user's app data to be automatically backed up to their Google Drive. If this is set to false, no backup or restore of the application will ever be performed (this is useful if your app deals with sensitive information). Defaults to the Android default, which is `true`. #### `softwareKeyboardLayoutMode` Type: `enum` • One of: `resize`, `pan` • Path: `android.softwareKeyboardLayoutMode` Determines how the software keyboard will impact the layout of your application. This maps to the `android:windowSoftInputMode` property. Defaults to `resize`. Valid values: `resize`, `pan`. #### `runtimeVersion` One of types: - `string` matching the following pattern: `^[a-zA-Z\d][a-zA-Z\d._+()-]{0,254}$` - `string` matching the following pattern: `^exposdk:((\d+\.\d+\.\d+)|(UNVERSIONED))$` - An `object` with the following properties: ##### `policy` Type: `enum` • Path: `android.runtimeVersion.policy` Valid values: `nativeVersion`, `sdkVersion`, `appVersion`, `fingerprint`. Property indicating compatibility between a Android build's native code and an OTA update for the Android platform. If provided, this will override the value of top level `runtimeVersion` key on Android. #### `version` Type: `string` • Path: `android.version` Your android app version. Takes precedence over the root `version` field. In addition to this field, you'll also use `android.versionCode` — read more about how to version your app [here](https://docs.expo.dev/distribution/app-stores/#versioning-your-app). This corresponds to `versionName`. The required format can be found [here](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring). Existing React Native app? To change your app version, edit the `versionName` string in `android/app/build.gradle` #### `predictiveBackGestureEnabled` Type: `boolean` • Path: `android.predictiveBackGestureEnabled` Enable your app to use the [predictive back gesture](https://developer.android.com/guide/navigation/custom-back/predictive-back-gesture) on Android 13 (API level 33) and later. Default to false. Existing React Native app? To change the setting, update the `android:enableOnBackInvokedCallback` value in `AndroidManifest.xml`. ### `web` Type: `object` Configuration that is specific to the web platform. #### `output` Type: `enum` • One of: `single`, `static`, `server` • Path: `web.output` Sets the export method for the web app for both `expo start` and `expo export`. `static` statically renders HTML files for every route in the `app/` directory, which is available only in Expo Router apps. `single` outputs a Single Page Application (SPA), with a single `index.html` in the output folder, and has no statically indexable HTML. `server` outputs static HTML, and API Routes for hosting with a custom Node.js server. Defaults to `single`. #### `favicon` Type: `string` • Path: `web.favicon` Relative path of an image to use for your app's favicon. #### `name` Type: `string` • Path: `web.name` Defines the title of the document, defaults to the outer level name #### `shortName` Type: `string` • Path: `web.shortName` A short version of the app's name, 12 characters or fewer. Used in app launcher and new tab pages. Maps to `short_name` in the PWA manifest.json. Defaults to the `name` property. Maximum 12 characters long #### `lang` Type: `string` • Path: `web.lang` Specifies the primary language for the values in the name and short_name members. This value is a string containing a single language tag. #### `scope` Type: `string` • Path: `web.scope` Defines the navigation scope of this website's context. This restricts what web pages can be viewed while the manifest is applied. If the user navigates outside the scope, it returns to a normal web page inside a browser tab/window. If the scope is a relative URL, the base URL will be the URL of the manifest. #### `themeColor` Type: `string` • Path: `web.themeColor` Defines the color of the Android tool bar, and may be reflected in the app's preview in task switchers. 6 character long hex color string, for example, `'#000000'` #### `description` Type: `string` • Path: `web.description` Provides a general description of what the pinned website does. #### `dir` Type: `enum` • One of: `auto`, `ltr`, `rtl` • Path: `web.dir` Specifies the primary text direction for the name, short_name, and description members. Together with the lang member, it helps the correct display of right-to-left languages. #### `display` Type: `enum` • One of: `fullscreen`, `standalone`, `minimal-ui`, `browser` • Path: `web.display` Defines the developers’ preferred display mode for the website. #### `startUrl` Type: `string` • Path: `web.startUrl` The URL that loads when a user launches the application (e.g., when added to home screen), typically the index. Note: This has to be a relative URL, relative to the manifest URL. #### `orientation` Type: `enum` • One of: `any`, `natural`, `landscape`, `landscape-primary`, `landscape-secondary`, `portrait`, `portrait-primary`, `portrait-secondary` • Path: `web.orientation` Defines the default orientation for all the website's top level browsing contexts. #### `backgroundColor` Type: `string` • Path: `web.backgroundColor` Defines the expected “background color” for the website. This value repeats what is already available in the site’s CSS, but can be used by browsers to draw the background color of a shortcut when the manifest is available before the stylesheet has loaded. This creates a smooth transition between launching the web application and loading the site's content. 6 character long hex color string, for example, `'#000000'` #### `barStyle` Type: `enum` • One of: `default`, `black`, `black-translucent` • Path: `web.barStyle` If content is set to default, the status bar appears normal. If set to black, the status bar has a black background. If set to black-translucent, the status bar is black and translucent. If set to default or black, the web content is displayed below the status bar. If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar. #### `preferRelatedApplications` Type: `boolean` • Path: `web.preferRelatedApplications` Hints for the user agent to indicate to the user that the specified native applications (defined in expo.ios and expo.android) are recommended over the website. #### `dangerous` Type: `object` • Path: `web.dangerous` Experimental features. These will break without deprecation notice. #### `splash` Type: `object` • Path: `web.splash` Configuration for PWA splash screens. Existing React Native app? Use [expo-splash-screen](https://github.com/expo/expo/tree/main/packages/expo-splash-screen#expo-splash-screen) ##### `backgroundColor` Type: `string` • Path: `web.splash.backgroundColor` Color to fill the loading screen background 6 character long hex color string, for example, `'#000000'` ##### `resizeMode` Type: `enum` • One of: `cover`, `contain` • Path: `web.splash.resizeMode` Determines how the `image` will be displayed in the splash loading screen. Must be one of `cover` or `contain`, defaults to `contain`. ##### `image` Type: `string` • Path: `web.splash.image` Local path or remote URL to an image to fill the background of the loading screen. Image size and aspect ratio are up to you. Must be a .png. #### `config` Type: `object` • Path: `web.config` Firebase web configuration. Used by the expo-firebase packages on both web and native. [Learn more](https://firebase.google.com/docs/reference/js/firebase.html#initializeapp) ##### `firebase` Type: `object` • Path: `web.config.firebase` ##### `apiKey` Type: `string` • Path: `web.config.firebase.apiKey` ##### `authDomain` Type: `string` • Path: `web.config.firebase.authDomain` ##### `databaseURL` Type: `string` • Path: `web.config.firebase.databaseURL` ##### `projectId` Type: `string` • Path: `web.config.firebase.projectId` ##### `storageBucket` Type: `string` • Path: `web.config.firebase.storageBucket` ##### `messagingSenderId` Type: `string` • Path: `web.config.firebase.messagingSenderId` ##### `appId` Type: `string` • Path: `web.config.firebase.appId` ##### `measurementId` Type: `string` • Path: `web.config.firebase.measurementId` #### `bundler` Type: `enum` • One of: `webpack`, `metro` • Path: `web.bundler` Sets the bundler to use for the web platform. Only supported in the local CLI `npx expo`. Defaults to `webpack` if the `@expo/webpack-config` package is installed, if not, it defaults to `metro`. ### `experiments` Type: `object` Enable experimental features that may be unstable, unsupported, or removed without deprecation notices. #### `autolinkingModuleResolution` Type: `boolean` • Path: `experiments.autolinkingModuleResolution` Apply Expo Autolinking's search results to Metro's module resolution. This forces your project's dependencies on `react`, `react-dom`, and `react-native`, and the autolinked versions of any Expo and React Native modules to be resolved when bundling your app. This prevents version misalignment and is useful for monorepos and to prevent conflicts. #### `baseUrl` Type: `string` • Path: `experiments.baseUrl` Export a website relative to a subpath of a domain. The path will be prepended as-is to links to all bundled resources. Prefix the path with a `/` (recommended) to load all resources relative to the server root. If the path **does not** start with a `/` then resources will be loaded relative to the code that requests them, this could lead to unexpected behavior. Example '/subpath'. Defaults to '' (empty string). #### `buildCacheProvider` > Deprecated Type: `undefined` • Path: `experiments.buildCacheProvider` This field is not longer marked as experimental and will be removed in a future release, use the `buildCacheProvider` field instead. #### `supportsTVOnly` Type: `boolean` • Path: `experiments.supportsTVOnly` If true, indicates that this project does not support tablets or handsets, and only supports Apple TV and Android TV #### `functionalCSS` Type: `boolean` • Path: `experiments.functionalCSS` Enable React-based CSS support for native platforms. Only supports a subset of CSS properties, class names selectors, and has no cascading. #### `tsconfigPaths` Type: `boolean` • Path: `experiments.tsconfigPaths` Enable tsconfig/jsconfig `compilerOptions.paths` and `compilerOptions.baseUrl` support for import aliases in Metro. #### `typedRoutes` Type: `boolean` • Path: `experiments.typedRoutes` Enable support for statically typed links in Expo Router. This feature requires TypeScript be set up in your Expo Router v2 project. #### `turboModules` Type: `boolean` • Path: `experiments.turboModules` Enables Turbo Modules, which are a type of native modules that use a different way of communicating between JS and platform code. When installing a Turbo Module you will need to enable this experimental option (the library still needs to be a part of Expo SDK already, like react-native-reanimated v2). Turbo Modules do not support remote debugging and enabling this option will disable remote debugging. #### `reactCanary` Type: `boolean` • Path: `experiments.reactCanary` Experimentally use a vendored canary build of React for testing upcoming features. #### `reactCompiler` Type: `boolean` • Path: `experiments.reactCompiler` Experimentally enable React Compiler. #### `reactServerComponentRoutes` Type: `boolean` • Path: `experiments.reactServerComponentRoutes` Experimentally enable React Server Components by default in Expo Router and concurrent routing for transitions. #### `reactServerFunctions` Type: `boolean` • Path: `experiments.reactServerFunctions` Experimentally enable React Server Functions support in Expo CLI and Expo Router. ### `_internal` Type: `object` Internal properties for developer tools #### `pluginHistory` Type: `object` • Path: `_internal.pluginHistory` List of plugins already run on the config --- --- title: babel.config.js description: Babel 配置文件参考。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/versions/latest/config/babel/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # babel.config.js Babel 配置文件参考。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. Babel 用作 JavaScript 编译器,将现代 JavaScript(ES6+)转换为与移动设备上的 JavaScript 引擎兼容的版本。 使用 `npx create-expo-app` 创建的每个新 Expo 项目都会自动配置 Babel,并使用 [`babel-preset-expo`](https://github.com/expo/expo/tree/main/packages/babel-preset-expo) 作为默认预设。除非你需要自定义 Babel 配置,否则无需创建 **babel.config.js** 文件。 ## 创建 babel.config.js 如果你的项目需要自定义 Babel 配置,你需要按照以下步骤在项目中创建 **babel.config.js** 文件: 1. 导航到项目根目录,并在终端中运行以下命令。这将会在项目根目录生成一个 **babel.config.js** 文件。 ```sh npx expo customize babel.config.js ``` 2. **babel.config.js** 文件包含以下默认配置: ```js module.exports = function (api) { api.cache(true); return { presets: ['babel-preset-expo'], }; }; ``` 3. 如果你对 **babel.config.js** 文件进行了更改,你需要重启 Metro 打包器以应用这些更改,并在 Expo CLI 中使用 `--clear` 选项来清除 Metro 打包器缓存: ```sh npx expo start --clear ``` ## babel-preset-expo [`babel-preset-expo`](https://github.com/expo/expo/tree/main/packages/babel-preset-expo) 是 Expo 项目中使用的默认预设。它扩展了默认的 React Native 预设(`@react-native/babel-preset`),并增加了对装饰器、Web 库的 tree-shaking 以及加载字体图标的支持。 --- --- title: metro.config.js description: Metro 中可用配置的参考。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/versions/latest/config/metro/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # metro.config.js Metro 中可用配置的参考。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. 查看更多关于 **metro.config.js** 的信息,请参阅 [自定义 Metro 指南](/guides/customizing-metro)。 ## 环境变量 Expo CLI 可以从 **.env** 文件中加载环境变量。有关如何在 Expo CLI 中使用环境变量的更多信息,请参阅 [环境变量指南](/guides/environment-variables)。 EAS CLI 对环境变量使用不同的机制,除非它在编译和打包时调用 Expo CLI。了解更多关于 [EAS 中的环境变量](/eas/environment-variables)。 如果你正在迁移一个较旧的项目,那么你应该通过在 **.gitignore** 中添加以下内容来忽略本地 env 文件: ```sh # 本地 env 文件 .env*.local ``` ### 禁用 dotenv 文件 可以在调用任何 Expo CLI 命令之前,通过启用 `EXPO_NO_DOTENV` 环境变量,来完全禁用 Expo CLI 加载 dotenv 文件。 ```sh npx cross-env EXPO_NO_DOTENV=1 expo start EXPO_NO_DOTENV=1 npx expo start ``` ### 禁用以 `EXPO_PUBLIC_` 为前缀的客户端环境变量 以 `EXPO_PUBLIC_` 为前缀的环境变量会在构建时暴露给应用。例如,`EXPO_PUBLIC_API_KEY` 将可作为 `process.env.EXPO_PUBLIC_API_KEY` 使用。 可以使用环境变量 `EXPO_NO_CLIENT_ENV_VARS=1` 来禁用客户端环境变量内联,这必须在进行任何打包之前定义。 ```sh npx cross-env EXPO_NO_CLIENT_ENV_VARS=1 expo start EXPO_NO_CLIENT_ENV_VARS=1 npx expo start ``` ## CSS > **信息** CSS 支持仍在开发中,目前仅适用于 web。 Expo 支持你项目中的 CSS。你可以从任何组件中导入 CSS 文件。CSS Modules 也受支持。 CSS 支持默认启用。你可以通过在 Metro 配置中设置 `isCSSEnabled` 来禁用该功能。 ```js /** @type {import('expo/metro-config').MetroConfig} */ const config = getDefaultConfig(__dirname, { // 禁用 CSS 支持。 isCSSEnabled: false, }); ``` ### 全局 CSS > **警告** 全局样式仅限 web 使用,使用它会导致你的应用在原生平台上的视觉表现发生偏差。 你可以从任何组件导入一个 CSS 文件。该 CSS 将应用到整个页面。 这里,我们将为类名 `.container` 定义一个全局样式: ```css .container { background-color: red; } ``` 然后我们可以通过导入样式表并使用 `.container` 来在组件中使用这个类名: ```jsx import './styles.css'; import { View } from 'react-native'; export default function App() { return ( <> {/* 使用 `className` 为 React DOM 组件分配样式。 */}
Hello World
{/* 使用以下语法配合 `style`,为 React Native web 追加类名。 */} Hello World ); } ``` 你也可以像导入任何 node 模块一样,导入库中捆绑的样式表: ```js // 将样式应用到整个应用。 import 'emoji-mart/css/emoji-mart.css'; ``` - 在原生平台上,所有全局样式表都会被自动忽略。 - 全局样式表支持热重载,只需保存文件,变更就会应用。 > **警告** 使用 Expo Router 时,请始终在根目录的 **_layout.tsx** 中导入全局 CSS。Expo Router 会从根布局开始遍历依赖图。在嵌套布局中导入 CSS 会导致 **node_modules** 中的 CSS 在你的自定义样式之前加载,从而可能破坏你预期的样式顺序。 ### CSS Modules > **警告** 原生平台的 CSS Modules 仍在开发中,目前仅适用于 web。 CSS Modules 是一种将 CSS 限定在特定组件范围内的方法。这有助于避免命名冲突,并确保样式只应用于预期的组件。 在 Expo 中,CSS Modules 通过创建一个扩展名为 `.module.css` 的文件来定义。该文件可以从任何组件中导入。导出的值是一个对象,类名作为键,仅限 web 的作用域名称作为值。可以使用 `unstable_styles` 导入来访问对 `react-native-web` 安全的样式。 CSS Modules 支持平台扩展名,允许你为不同平台定义不同的样式。例如,你可以定义 `module.ios.css` 和 `module.android.css` 文件,分别为 Android 和 iOS 定义样式。你需要在导入时不带扩展名,例如: 例如,反转扩展名,`App.ios.module.css` 将不起作用,并会生成一个名为 `App.ios.module` 的通用模块。 > 你不能将样式传递给 React Native 或 React Native for web 组件的 `className` 属性。相反,你必须使用 `style` 属性。 ```jsx import styles, { unstable_styles } from './App.module.css'; export default function Page() { return ( <> Hello World Hello World {/* 仅限 web 的用法: */}

Hello World

); } ``` ```css .text { color: red; } ``` - 在 web 上,所有 CSS 值都可用。CSS 不会像 React Native Web 的 `StyleSheet` API 那样被处理或自动添加前缀。你可以使用 `postcss.config.js` 为你的 CSS 自动添加前缀。 - CSS Modules 底层使用 [lightningcss](https://github.com/parcel-bundler/lightningcss),请查看 [这些 issue](https://github.com/parcel-bundler/lightningcss/issues) 了解不受支持的功能。 ### PostCSS 可以通过在项目根目录添加 `postcss.config.json` 文件来自定义 [PostCSS](https://github.com/postcss/postcss)。该文件应导出一个返回 PostCSS 配置对象的函数。例如: ```json { "plugins": { "tailwindcss": {} } } ``` `postcss.config.json` 和 `postcss.config.js` 都受支持,但 `postcss.config.json` 可以实现更好的缓存。 Expo CLI 会借助对 [browserslist](https://browsersl.ist/) 的内置支持,自动处理 CSS 厂商前缀。请避免添加 `autoprefixer`,因为这会重复该功能并减慢打包速度。 #### 更新后重置缓存 更改 Post CSS 或 `browserslist` 配置后,需要清除 Metro 缓存: ```sh npx expo start --clear npx expo export --clear ``` ### browserslist Expo 通过基于 Rust 的 CSS 解析器自动支持 [browserslist](https://browsersl.ist/)。你可以通过在 **package.json** 文件中添加 **browserslist** 字段来自定义 CSS 厂商前缀和浏览器支持。例如: ```json { "browserslist": [">0.2%", "not dead", "not op_mini all"] } ``` ### SASS Expo Metro 对 SCSS/SASS 提供 _部分_ 支持。 要进行设置,请在项目中安装 `sass` 包: ```sh yarn add -D sass ``` 然后,确保在 **metro.config.js** 文件中已完成 [CSS 设置](/versions/latest/config/metro#css)。 - 当安装了 `sass` 时,不带扩展名的模块将按以下顺序解析:`scss`、`sass`、`css`。 - 仅在 `sass` 文件中使用预期的语法。 - 当前不支持从 scss/sass 文件内部导入其他文件。 ### Tailwind > **信息** 标准 Tailwind CSS 仅支持 web 平台。若要获得通用支持,请使用类似 [NativeWind](https://www.nativewind.dev/) 或 [Uniwind](https://uniwind.dev/) 的库,它们允许使用 Tailwind CSS 创建带样式的 React Native 组件。 [Tailwind CSS](/guides/tailwind) — 了解如何在你的 Expo 项目中配置和使用 Tailwind CSS。 ## 扩展 Babel 转换器 Expo 的 Metro 配置使用自定义的 `transformer.babelTransformerPath` 值,以确保始终使用 `expo-babel-preset` 并支持 web/Node.js 环境。 如果你想扩展 Babel 转换器,请从 `@expo/metro-config/babel-transformer` 导入上游转换器,而不是 `metro-react-native-babel-transformer`。例如: ```js const upstreamTransformer = require('@expo/metro-config/babel-transformer'); module.exports.transform = async ({ src, filename, options }) => { // 对 SVG 文件执行一些自定义处理... if (filename.endsWith('.svg')) { src = '...'; } // 将源代码传递给上游 Expo 转换器。 return upstreamTransformer.transform({ src, filename, options }); }; ``` ## 自定义解析 Expo CLI 扩展了默认的 Metro 解析器,以添加 Web、Server 和 tsconfig 别名支持等功能。你也可以通过链式调用 `config.resolver.resolveRequest` 函数来类似地自定义 Metro 的默认解析行为。 ```tsx const { getDefaultConfig } = require('expo/metro-config'); /** @type {import('expo/metro-config').MetroConfig} */ const config = getDefaultConfig(__dirname); config.resolver.resolveRequest = (context, moduleName, platform) => { if (moduleName.startsWith('my-custom-resolver:')) { // 将模块名解析为文件路径的逻辑... // 注意:如果无法解析,请抛出错误。 return { filePath: 'path/to/file', type: 'sourceFile', }; } // 确保你调用默认解析器。 return context.resolveRequest(context, moduleName, platform); }; module.exports = config; ``` 与传统打包器不同,Metro 在所有平台上共享同一个解析器函数。因此,你可以使用 `context` 对象在每次请求时动态修改解析设置。 ### 模拟模块 如果你希望某个平台上的某个模块为空,可以从解析器返回 `type: 'empty'` 对象。下面的示例会使 `lodash` 在 web 上为空: ```ts const { getDefaultConfig } = require('expo/metro-config'); /** @type {import('expo/metro-config').MetroConfig} */ const config = getDefaultConfig(__dirname); config.resolver.resolveRequest = (context, moduleName, platform) => { if (platform === 'web' && moduleName === 'lodash') { return { type: 'empty', }; } // 确保你调用默认解析器。 return context.resolveRequest(context, moduleName, platform); }; module.exports = config; ``` 这种技术等同于在 Webpack 或 Vite 中使用空外部依赖,但额外的好处是可以针对特定平台。 ### 虚拟模块 Metro 目前不支持虚拟模块。你可以使用的一种类似方式,是在 `node_modules/.cache/...` 目录中创建一个模块,并将解析重定向到该文件。 下面的示例会在 `node_modules/.cache/virtual/virtual-module.js` 中创建一个模块,并将 `virtual:my-module` 的解析重定向到该文件: ```ts const path = require('path'); const fs = require('fs'); const { getDefaultConfig } = require('expo/metro-config'); /** @type {import('expo/metro-config').MetroConfig} */ const config = getDefaultConfig(__dirname); const virtualPath = path.resolve(__dirname, 'node_modules/.cache/virtual/virtual-module.js'); // 在生成目录中创建虚拟模块... fs.mkdirSync(path.dirname(virtualPath), { recursive: true }); fs.writeFileSync(virtualPath, 'export default "Hello World";'); config.resolver.resolveRequest = (context, moduleName, platform) => { if (moduleName === 'virtual:my-module') { return { filePath: virtualPath, type: 'sourceFile', }; } // 确保你调用默认解析器。 return context.resolveRequest(context, moduleName, platform); }; module.exports = config; ``` 这可用于通过自定义导入来模拟 `externals`。例如,如果你想将 `require('expo')` 重定向到类似 `SystemJS.require('expo')` 的自定义内容,你可以创建一个导出 `SystemJS.require('expo')` 的虚拟模块,并将 `expo` 的解析重定向到该文件。 ## 自定义转换 > 转换在 Metro 中有大量缓存。如果你更新了某些内容,请使用 `--clear` 标志查看更新。例如,`npx expo start --clear`。 Metro 没有非常强大的用于转换文件的插件系统,因此改为使用 [**babel.config.js**](/versions/latest/config/babel) 和 caller 对象来自定义转换。 ```js module.exports = function (api) { // 获取 Expo CLI 正在为其转换的平台。 const platform = api.caller(caller => (caller ? caller.platform : 'ios')); // 检测打包操作是否用于 Hermes 引擎,例如 `'hermes'` | `undefined`。 const engine = api.caller(caller => (caller ? caller.engine : null)); // 是否为服务器环境进行打包,例如 API Routes。 const isServer = api.caller(caller => (caller ? caller.isServer : false)); // 是否为开发或生产环境进行打包。 const isDev = api.caller(caller => caller ? caller.isDev : process.env.BABEL_ENV === 'development' || process.env.NODE_ENV === 'development' ); // 确保配置不会被缓存,否则平台将不会更新。 api.cache(false); // 你也可以提供一种更健壮的 CONFIG 缓存失效方式: // api.cache.invalidate(() => platform); return { presets: ['babel-preset-expo'], plugins: [ // 基于平台添加一个插件... platform === 'web' && 'my-plugin', // 确保过滤掉假值。 ].filter(Boolean), }; }; ``` 如果 caller 没有 `engine`、`platform`、`bundler` 等信息,那么请确保你使用的是用于 transformer 的 `@expo/metro-config/babel-transformer`。如果你使用的是自定义 transformer,那么它可能需要扩展 Expo transformer。 如果可能,请始终尝试在 resolver 中实现自定义逻辑,因为缓存会简单得多,也更容易理解。例如,如果你需要重映射一个 import,那么使用 resolver 将其解析到一个静态文件,比解析所有可能的导入方式并用 transformer 重新映射它们更简单也更快。 始终使用 `babel-preset-expo` 作为默认的 Babel preset,这可确保转换始终与 Expo 运行时兼容。`babel-preset-expo` 会在内部使用所有 caller 输入,以便针对给定的平台、引擎和环境进行优化。 ## Node.js 内置模块 当为服务器环境打包时,Expo 的 Metro 配置会根据当前 Node.js 版本自动支持将 Node.js 内置模块(`fs`、`path`、`node:crypto` 等)外部化。如果 CLI 正在为浏览器环境打包,那么内置模块会先检查该模块是否已在本地安装,然后回退到一个空的 shim。例如,如果你安装了用于浏览器中的 `path`,则可以使用它;否则,该模块会自动被跳过。 ## 环境设置 > 这些环境变量不会在测试环境中定义。 Expo 的 Metro 配置会注入构建设置,这些设置可以通过环境变量在客户端 bundle 中使用。所有变量都会被内联,不能动态使用。例如,`process.env["EXPO_BASE_URL"]` 将不起作用。 - `process.env.EXPO_BASE_URL` 会暴露在 `experiments.baseUrl` 中定义的基础 URL。这在 Expo Router 中用于在部署时遵守生产环境的基础 URL。 ## Bundle 拆分 Expo CLI 会在生产环境中根据异步导入自动将 web bundle 拆分为多个 chunk。此功能要求安装 `@expo/metro-runtime`,并且在入口 bundle 的某处被导入(在 Expo Router 中默认可用)。 异步 bundle 的共享依赖会合并到单个 chunk 中,以减少请求次数。例如,如果你有两个异步 bundle 都导入了 `lodash`,那么该库会被合并到一个初始 chunk 中。 chunk 拆分的启发式规则无法自定义。例如: `math.js` `index.js` ```js export function add(a, b) { return a + b; } ``` ```js import '@expo/metro-runtime'; // 这将被拆分到一个单独的 chunk 中。 import('./math').then(math => { console.log(math.add(1, 2)); }); ``` 当你运行 `npx expo export -p web` 时,bundle 会被拆分为多个文件,入口 bundle 会被添加到主 HTML 文件中。`@expo/metro-runtime` 会添加用于加载并执行异步 bundle 的运行时代码。 ## Source map debug ID 如果一个 bundle 导出时带有外部 source map,那么会在文件末尾添加一个 [**Debug ID**](https://sentry.engineering/blog/the-case-for-debug-ids) 注解,并在 source map 中添加匹配的 `debugId`,以便将这些文件对应起来。如果未导出 source map,或者使用的是内联 source map,则不会添加该注解。 ```js // <所有源代码> //# debugId= ``` 相关联的 `*.js.map` 或 `*.hbc.map` source map 会是一个 JSON 文件,其中包含等效的 `debugId` 属性。`debugId` 会在 hermes 字节码生成之前注入,以确保在所有情况下都能匹配。 `debugId` 是 bundle 内容的确定性哈希,但不包含外部 bundle 拆分引用。这与用于创建 chunk 文件名的值相同,只是格式化为 UUID。例如,`431b98e2-c997-4975-a3d9-2987710abd44`。 `@expo/metro-config` 会在 `npx expo export` 和 `npx expo export:embed` 期间注入 `debugId`。`npx expo export:embed` 中的任何额外优化步骤,例如 Hermes 字节码生成,都需要手动注入 `debugId`。 ## Metro require 运行时 你可以通过环境变量 `EXPO_USE_METRO_REQUIRE=1` 可选地启用自定义 Metro `require` 实现。该运行时具有以下特性: - 使用人类可读的字符串模块 ID,使缺失模块错误更容易追踪。 - 具有确定性 ID,在多次运行之间以及跨模块都保持一致(开发环境中的 React Server Components 需要此特性)。 - 移除了对旧版 RAM bundle 的支持。 ## Magic import 注释 > 从 SDK 52 起在所有平台可用。 诸如 Workers 和 Node.js 等服务器环境支持在运行时导入任意文件,因此你可能希望保持 `import` 语法不变,而不是使用 Metro 的 require 系统。你可以在 `import()` 语句中使用 `/* @metro-ignore */` 注释来选择不使用动态导入。 ```js // 手动确保 `./my-module.js` 被包含在相对于模块的正确位置。 const myModule = await import(/* @metro-ignore */ './my-module.js'); ``` Expo CLI 会跳过 `./my-module.js` 依赖,并假定开发者已将其手动添加到输出 bundle 中。在内部,这用于导出自定义服务器代码,该代码会根据请求在文件之间动态切换。避免在原生 bundle 中使用此语法,因为在启用 Hermes 的 React Native 中通常无法使用 `import()`。 许多 React 库都提供了 Webpack 的 `/* webpackIgnore: true */` 注释来实现类似行为。为了弥合差异,我们也添加了对 Webpack 注释的支持,但建议你在应用中使用 Metro 对应的写法。 ## ES 模块解析 > 本节适用于从 SDK 53 起的所有平台。 Metro 会为 ES Module 的 `import` 和 CommonJS 的 `require` 使用不同的解析策略。 之前,Metro 采用经典的 Node.js 模块解析策略(与 v12 之前的 Node.js 版本一致),并做了一些额外调整来支持 ES Modules。在这种解析策略下,Metro 会从 `node_modules`、JS 文件中解析模块,必要时可以省略扩展名(例如 `.js`),并使用 `package.json` 中的 `main`、`module` 和 `react-native` 等字段。 现在,随着现代 ES Modules 解析策略的引入,Metro 会先从 `node_modules` 中解析模块,然后匹配不同的 `package.json` 字段,例如 `exports`、[包暴露的子路径的嵌套映射](https://nodejs.org/api/packages.html#conditional-exports) 和 `main`。 根据包的导入方式,这两种解析策略中的一种会被使用。通常,从 Node 模块中使用 `import` 导入的文件(而不是 `require`)会使用 ES Modules 解析策略,并在必要时回退到常规经典 Node.js 解析。未使用 ES Modules 解析,或者通过 CommonJS `require` 导入的文件,则会使用经典解析策略。 ### `package.json:exports` 在执行 ES Modules 解析时,Metro 会查看 `package.json:exports` 条件映射。这个映射将导入子路径和条件映射到 Node 模块包中的文件。 例如,一个始终暴露 **index.js** 文件,并且符合 Metro 经典 CommonJS 模块解析的包,可以通过 `default` 条件指定一个映射。 ```json { "exports": { "default": "./index.js" } } ``` 不过,同时提供 CommonJS 和 ES Modules 入口点的包,可以通过 `import` 和 `require` 条件提供映射。 ```json { "exports": { "import": "./index.mjs", "require": "./index.cjs" } } ``` 默认情况下,Metro 会根据平台以及解析是从 CommonJS `require` 调用开始,还是从 ES Modules `import` 语句开始,来匹配不同的条件,并相应地更改条件。 对于原生平台,会添加 `react-native` 条件;对于 web 导出,会添加 `browser` 条件;对于服务器导出(例如 API routes 或 React Server functions),会添加 `node`、`react-server` 和 `workerd` 条件。这些条件不会按照它们定义的顺序匹配,而是会按照 `package.json:exports` 映射中的属性顺序进行匹配。 TypeScript 会独立于 Metro 执行 ES Module 解析,并且在其 `compilerOptions.moduleResolution` 配置选项设置为 `"bundler"`(这与 Metro 的行为更接近)或 `"node16"` / `"nodenext"` 时,也会遵守 `package.json:exports` 映射。不过,TypeScript 还会匹配 `types` 条件。因此,当某个包没有把 `types` 条件放在其 exports 映射的首位时,类型可能无法正确解析。 由于 exports 映射可能包含子路径,包导入不再一定需要匹配包 modules 文件夹中的某个文件,而可能是一个“重定向”导入。如果在 `package.json:exports` 中指定了,导入 `'package/submodule'` 可能会匹配到与 **node_modules/package/submodule.js** 不同的文件。 ```json { "exports": { ".": "./index.js", "./submodule": "./submodule/submodule.js" } } ``` 如果你遇到与新的 ES Modules 解析策略不兼容或尚未准备好的包,你可以通过补丁修改其 `package.json` 文件并添加或修正其 `package.json:exports` 条件映射来解决问题。不过,也可以通过禁用 `unstable_enablePackageExports` 选项来阻止 Metro 在解析中使用 `package.json:exports` 映射。 ```js const { getDefaultConfig } = require('expo/metro-config'); /** @type {import('expo/metro-config').MetroConfig} */ const config = getDefaultConfig(__dirname); config.resolver.unstable_enablePackageExports = false; module.exports = config; ``` ## 资产导入 当导入资产时,会创建一个虚拟模块来表示导入该资产所需的数据。 在原生平台上,资产将是一个数字 ID:`1`、`2`、`3`,等等,可以通过 `require("@react-native/assets-registry/registry").getAssetByID()` 来查找。在 web 和服务器平台上,资产会根据文件类型而变化。如果文件是图片,那么资产将是 `{ uri: string, width?: number, height?: number }`,否则资产将是一个表示该资产远程 URL 的 `string`。从 SDK 55 起,你可以使用 `String(asset)` 来获取 web 上任意资产的公开 URL,这不包括无法包含 `toString` 函数的 React Server Component 环境。 资产可以如下使用: ```jsx import { Image } from 'react-native'; import asset from './img.png'; function Demo() { return ; } ``` 在 API 路由中,你始终可以假设资产的类型不会是数字: ```js import asset from './img.png'; export async function GET(req: Request) { const ImageData = await fetch( new URL( // 访问资产 URI。 asset.uri, // 附加到当前请求 URL 的 origin。 req.url ) ).then(res => res.arrayBuffer()); return new Response(ImageData, { headers: { 'Content-Type': 'image/png', }, }); } ``` ## Web workers > **重要** 此功能为 [alpha](/more/release-statuses#alpha) 版本,并可能发生破坏性变更。 ```ts new Worker(new URL('./worker', window.location.href)); ``` Expo Metro 提供实验性的 web worker 支持。此功能目前仅支持 web,不能在原生平台上使用,在原生平台上使用会触发错误 "Property 'Worker' doesn't exist"。 Web worker 可用于将工作卸载到 web 上的单独线程,从而让主线程保持响应。这对于计算开销较大的任务很有用,例如图像处理、加密或其他会阻塞主线程的任务。 Worker 可以使用 `Blob` 内联生成,但有时你可能希望利用 TypeScript 等现代特性,或导入其他模块。 Web worker 依赖于 Expo 的 bundle 拆分支持,这意味着你需要使用 Expo Router,或者安装并导入 `@expo/metro-runtime`。你也不能在 web worker 中使用环境变量 `EXPO_NO_METRO_LAZY=1`。 请看下面这个将数字翻倍的 worker 示例: ```ts self.onmessage = ({ data }) => { const result = data * 2; // 示例:将数字翻倍 self.postMessage(result); }; ``` 这个 worker 文件可以在主应用中作为 `Worker` 导入: ```ts // worker 的类型为 `Worker` const worker = new Worker(new URL('./worker', window.location.href)); worker.onmessage = ({ data }) => { console.log(`Worker responded: ${data}`); }; worker.postMessage(5); ``` 在幕后,Expo CLI 正在生成如下代码: ```ts const worker = new Worker( new URL('/worker.bundle?platform=web&dev=true&etc', window.location.href) ); ``` 生成的 bundle URL 会根据开发/生产环境而变化,以确保 worker 被正确加载并打包。不同于传统的 bundle 拆分,worker 文件需要包含其自身对所有模块的副本,并且不能依赖主 bundle 中的公共模块。 原生 API `Worker` 传统上在 React Native 中不可用,并且 Expo SDK 也未提供,因此即使这个打包功能在技术上适用于所有平台,它也只对 web 有用。如果你希望同时支持原生平台,从理论上说你可以编写一个原生 Expo 模块来为 `Worker` API 提供 polyfill。或者,你也可以在 React Native Reanimated 中使用 "worklet" API,将工作卸载到原生端的单独线程。 另外,你也可以通过公共路径导入 Worker:先将一个转换后的 JS 文件放入 **public** 目录,然后在 worker 导入中使用一个变量引用它: ```ts // 这将避免转换,并直接使用公共路径。 const worker = new Worker('/worker.js'); // 这个变量会破坏转换,导致使用字面路径而不是转换后的路径。 const path = '/worker.js'; const anotherWorker = new Worker(new URL(path, window.location.href)); ``` 在 `Worker` 构造函数中使用变量不支持打包。若要检查内部 URL,你可以使用内部语法 `require.unstable_resolveWorker('./path/to/worker.js')` 来获取 URL 片段。 ## Bare workflow 设置 > 本指南是版本相关的,在升级/降级 Expo 时需要重新查看。或者,使用 [Expo Prebuild](/more/glossary-of-terms#prebuild) 来进行完全自动化的设置。 不使用 [Expo Prebuild](/more/glossary-of-terms#prebuild) 的项目必须配置原生文件,以确保始终使用 Expo Metro 配置来打包项目。 这些修改旨在分别将 `npx react-native bundle` 和 `npx react-native start` 替换为 `npx expo export:embed` 和 `npx expo start`。 ### metro.config.js 确保 **metro.config.js** 继承自 `expo/metro-config`: ```js const { getDefaultConfig } = require('expo/metro-config'); const config = getDefaultConfig(__dirname); module.exports = config; ``` ### `android/app/build.gradle` Android 的 **app/build.gradle** 必须配置为在生产打包时使用 Expo CLI。修改 `react` 配置对象: ### `ios/.xcodeproj/project.pbxproj` 在你的 **ios/.xcodeproj/project.pbxproj** 文件中,替换以下脚本: #### "Start Packager" 脚本 移除 **"Start Packager"** 脚本。必须在运行应用之前或之后使用 `npx expo` 启动开发服务器。 #### "Bundle React Native code and images" 脚本 或者,在 Xcode 项目中,选择 **"Bundle React Native code and images"** 构建阶段,并添加以下修改: > 你可以设置 `CLI_PATH`、`BUNDLE_COMMAND` 和 `ENTRY_FILE` 环境变量来覆盖这些默认值。 ### 自定义入口文件 默认情况下,React Native 仅支持使用根目录下的 `index.js` 文件作为入口文件(或类似 `index.ios.js` 这样的平台特定变体)。Expo 项目允许使用任意入口文件,但这需要额外的裸工作流设置。 #### 开发 可以通过使用 [`expo-dev-client`](/versions/latest/sdk/dev-client) 包来启用开发模式入口文件。或者,你也可以添加以下配置: #### 生产 在你的 **ios/.xcodeproj/project.pbxproj** 文件中,根据 Metro 将 **"Bundle React Native code and images"** 脚本替换为设置 `$ENTRY_FILE`: Android 的 **app/build.gradle** 必须配置为使用 Metro 模块解析来查找根入口文件。修改 `react` 配置对象: --- --- title: package.json description: package.json 文件中可使用的 Expo 特定属性参考。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/versions/latest/config/package-json/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # package.json package.json 文件中可使用的 Expo 特定属性参考。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. **package.json** 是一个 JSON 文件,包含 JavaScript 项目的元数据。这是对可在 **package.json** 文件中使用的 Expo 特定属性的参考。 ## `install.exclude` 以下命令会对项目中已安装的库执行版本检查,并在某个库的版本与 Expo 推荐的版本不同的时候给出警告: - `npx expo start` 和 `npx expo-doctor` - `npx expo install`(在安装该库的新版本时,或使用 `--check` 或 `--fix` 选项时) 通过在 **package.json** 文件中的 `install.exclude` 数组里指定该库,你可以将其排除在版本检查之外: ```json { "expo": { "install": { "exclude": ["expo-updates", "expo-splash-screen"] } } } ``` ## `autolinking` 允许通过在 **package.json** 中使用 `autolinking` 属性来配置模块解析行为。 完整参考请参见 [Autolinking configuration](/modules/autolinking#configuration)。 ## `doctor` 允许配置 [`npx expo-doctor`](/develop/tools#expo-doctor) 命令的行为。 ### `reactNativeDirectoryCheck` 默认情况下,Expo Doctor 会将你的项目包与 [React Native directory](https://reactnative.directory/) 进行验证。此检查会对未包含在 React Native Directory 中的包列表发出警告。 你可以通过在项目的 **package.json** 文件中添加以下配置来自定义此检查: ```json { "expo": { "doctor": { "reactNativeDirectoryCheck": { "enabled": true, "exclude": ["/foo/", "bar"], "listUnknownPackages": true } } } } ``` 默认情况下,此检查已启用,并会列出未知包。 ### `appConfigFieldsNotSyncedCheck` Expo Doctor 会检查你的项目是否包含原生项目目录,例如 **android** 或 **ios**。如果这些目录存在,但未列在你的 **.gitignore** 或 [**.easignore**](/build-reference/easignore) 文件中,Expo Doctor 会验证是否存在应用配置文件。如果该文件存在,这意味着你的项目已配置为使用 [Prebuild](/more/glossary-of-terms#prebuild)。 当 **android** 或 **ios** 目录存在时,EAS Build 不会将应用配置属性同步到原生项目。如果这些条件成立,Expo Doctor 会发出警告。 你可以通过在项目的 **package.json** 文件中添加以下配置来禁用或启用此检查: ```json { "expo": { "doctor": { "appConfigFieldsNotSyncedCheck": { "enabled": false } } } } ``` --- --- title: Expo SDK 参考 description: 使用 Expo SDK 包在你的 Expo 和 React Native 应用中访问设备和系统功能。 --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/versions/latest/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # Expo SDK 参考 使用 Expo SDK 包在你的 Expo 和 React Native 应用中访问设备和系统功能。 > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. Expo SDK 是一组提供访问设备和系统功能的包,例如相机、联系人、位置、传感器、触觉反馈等。每个包都针对特定功能,可独立使用。所有包都可在安装了 `expo` 包的任何 React Native 应用中正常工作。 您可以使用 [`npx expo install`](/more/expo-cli#install) 命令安装任意 Expo SDK 包。例如,以下命令会安装三个不同的包: ```sh npx expo install expo-camera expo-contacts expo-sensors ``` 安装一个或多个包后,您可以将它们导入到您的 JavaScript 代码中: ```js import { CameraView } from 'expo-camera'; import * as Contacts from 'expo-contacts'; import { Gyroscope } from 'expo-sensors'; ``` 这使您可以编写 [`Contacts.getContactsAsync()`](/versions/latest/sdk/contacts#contactsgetcontactsasynccontactquery) 并从设备读取联系人,读取陀螺仪传感器以检测设备移动,或者启动手机相机并拍照。 ## 所有 Expo SDK 包都可在任何 React Native 应用中使用 Expo 应用本质上就是 React Native 应用,因此所有 Expo SDK 包都可在安装并配置了 `expo` 包的任何 React Native 应用中使用。创建支持 Expo SDK 包的 React Native 应用最简单的方法是使用 `create-expo-app`。不过,您也可以通过 `npx install-expo-modules` 命令为现有的 React Native 应用添加 Expo SDK 支持。 ```sh npx create-expo-app my-app --template bare-minimum ``` [在现有 React Native 应用中安装 Expo SDK 包](/bare/installing-expo-modules) — 了解更多关于如何将使用 npx @react-native-community/cli@latest init 创建的项目配置为支持 Expo SDK 包。 — npx @react-native-community/cli@latest init [使用库](/workflow/using-libraries) — 了解如何在您的项目中安装 Expo SDK 包。 ## 使用预发布版本 新的 Expo SDK 版本每年发布三次。在这些发布之间,我们会发布 `expo` 包以及所有 Expo SDK 包的预发布版本。预发布版本不被视为稳定版,仅应在您能接受遇到 bug 或其他问题风险的情况下使用。 ### 金丝雀版本 金丝雀版本代表其发布时 `main` 分支状态的快照。金丝雀包版本名称中包含 `-canary`,以及日期和提交哈希,例如 `55.0.0-canary-20260121-a63c0dd`。要安装最新的金丝雀版本: ```sh npm install expo@canary && npx expo install --fix ``` 您通常可以将单个包的预发布版本与 Expo SDK 的稳定版本一起使用。金丝雀级别的发布有时可能会出现不兼容或其他问题。如果您选择使用金丝雀包,并且已验证其在您的使用场景中表现良好,您可能希望[关闭依赖验证警告](/more/expo-cli#configuring-dependency-validation)。 ### Beta 版本 在每次 Expo SDK 发布之前,我们都会发布 `expo` 包以及所有 Expo SDK 包的 beta 版本。Beta 版本被认为比金丝雀版本稳定得多,我们鼓励开发者在自己的应用中尝试它们并分享反馈。Beta 版本在 npm 上使用 `beta` 标签,并遵循相关 [更新日志](https://expo.dev/changelog) 帖子中的说明。 ## 每个 Expo SDK 版本都依赖于特定的 React Native 版本 | Expo SDK version | React Native version | React version | React Native Web version | React Native TV version | Minimum Node.js version | | --- | --- | --- | --- | --- | --- | | 55.0.0 | 0.83 | 19.2.0 | 0.21.0 | 0.83-stable | 20.19.x | | 54.0.0 | 0.81 | 19.1.0 | 0.21.0 | 0.81-stable | 20.19.x | | 53.0.0 | 0.79 | 19.0.0 | 0.20.0 | 0.79-stable | 20.18.x | ### 其他信息 Expo SDK 跟踪 React Native 发布的策略 - Expo SDK 版本每年发布三次,每个 Expo SDK 发布都对应一个 React Native 版本。通常是发布时最新的稳定版本。 - React Native 的发布节奏在其发展历史中有所变化,目前计划在 2025 年发布六次。在这样的节奏下,您可以预期每两个 React Native 版本都会对应一个 Expo SDK 版本。 - 即将发布的 Expo SDK 的预发布版本会很快支持最新版本的 React Native,通常在其发布当天即可支持。Expo SDK 团队的一名成员会参与每次 React Native 发布团队的工作,并负责持续更新 Expo 仓库中的 React Native 版本、验证兼容性,并将回归问题反馈给 Meta 团队。 为什么不在每次 React Native 发布后立即发布一个新的 Expo SDK 版本? 在 Expo,我们发现每年发布三个主要版本,能够在依赖我们开源工具的开发者所需的稳定性与创新之间取得良好平衡。Expo 与 Meta 在发布方面密切合作,我们将继续改进流程,以尽可能快地将最新的 Expo 和 React Native 功能带给您。 如果我需要最新 React Native 版本中的一个更改,但它还没有出现在 Expo SDK 发布中,该怎么办? 我们与 Meta 团队密切合作,确保任何紧急修复都会包含在最新 Expo SDK 所使用的 React Native 版本中。如果您的问题因为过于小众而无法被挑选进入现有版本,或者它涉及破坏性更改,那么您有两个选择: 1. 使用 [`patch-package`](https://github.com/ds300/patch-package) 引入该修复。 2. 使用 [Expo SDK 的预发布版本](/versions/latest#using-pre-release-versions)。([示例](https://expo.dev/changelog/react-native-78))。 我可以在最新的 Expo SDK 中使用较旧版本的 React Native 吗? Expo SDK 中的包旨在支持该 SDK 对应的目标 React Native 版本。通常,它们不支持较旧版本的 React Native,但也可能支持。当发布新的 React Native 版本时,Expo SDK 包的最新版本通常会更新以支持它。不过,这可能需要数周甚至更久,具体取决于该版本中的变更范围。 ## 对 Android 和 iOS 版本的支持 每个版本的 Expo SDK 都支持 Android 和 iOS 的最低操作系统版本。对于 Android,定义了 `compileSdkVersion`,它会告诉 [Gradle](https://developer.android.com/studio/build) 使用哪个 Android SDK 版本来编译应用。这也意味着您可以使用该 SDK 版本以及之前版本中包含的 Android API 功能。对于 iOS,[Xcode](https://developer.apple.com/news/upcoming-requirements/) 会指定用于编译应用的最低 Xcode SDK 版本。 | Expo SDK version | Android version | `compileSdkVersion` | `targetSdkVersion` | iOS version | Xcode version | | --- | --- | --- | --- | --- | --- | | 55.0.0 | 7+ | 36 | 36 | 15.1+ | 26.2+ | | 54.0.0 | 7+ | 36 | 36 | 15.1+ | 16.1+ | | 53.0.0 | 7+ | 35 | 35 | 15.1+ | 16.0+ | 在决定是否升级 Expo SDK 版本时,请同时考虑 Expo 的 SDK 版本和应用商店提交要求,如上表所述。Google Play 商店和 Apple App Store 会定期提高最低所需的操作系统版本和 API 等级,而这些是提交新应用所必需的。Expo 无法控制应用商店的要求,您应查看 [Google](https://developer.android.com/studio/build) 和 [Apple](https://developer.apple.com/news/upcoming-requirements/) 以了解当前的应用商店提交要求。 --- --- title: 加速度计 description: 一个提供访问设备加速度计传感器的库。 sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-sensors' packageName: 'expo-sensors' iconUrl: '/static/images/packages/expo-sensors.png' platforms: ['android', 'ios*', 'web', 'expo-go'] --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/versions/latest/sdk/accelerometer/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # Expo 加速度计 一个提供访问设备加速度计传感器的库。 Android, iOS (device only), Web, Included in Expo Go > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. `expo-sensors` 中的 `Accelerometer` 提供对设备加速度计传感器及相关监听器的访问,用于响应三维空间中加速度的变化,也就是任何移动或振动。 ## 安装 ```sh npx expo install expo-sensors ``` If you are installing this in an [existing React Native app](/bare/overview), make sure to [install `expo`](/bare/installing-expo-modules) in your project. ## 用法 ```jsx import { useState, useEffect } from 'react'; import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { Accelerometer } from 'expo-sensors'; export default function App() { const [{ x, y, z }, setData] = useState({ x: 0, y: 0, z: 0, }); const [subscription, setSubscription] = useState(null); const _slow = () => Accelerometer.setUpdateInterval(1000); const _fast = () => Accelerometer.setUpdateInterval(16); const _subscribe = () => { setSubscription(Accelerometer.addListener(setData)); }; const _unsubscribe = () => { subscription && subscription.remove(); setSubscription(null); }; useEffect(() => { _subscribe(); return () => _unsubscribe(); }, []); return ( 加速度计:(单位为 g,其中 1g = 9.81 m/s^2) x: {x} y: {y} z: {z} {subscription ? '开启' : '关闭'} ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', paddingHorizontal: 20, }, text: { textAlign: 'center', }, buttonContainer: { flexDirection: 'row', alignItems: 'stretch', marginTop: 15, }, button: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#eee', padding: 10, }, middleButton: { borderLeftWidth: 1, borderRightWidth: 1, borderColor: '#ccc', }, }); ``` ## API ```js import { Accelerometer } from 'expo-sensors'; ``` ## Classes ### `Accelerometer` Supported platforms: Android, iOS, Web. Type: Class extends [DeviceSensor](/versions/latest/sdk/sensors)<[AccelerometerMeasurement](#accelerometermeasurement)\> A base class for subscribable sensors. The events emitted by this class are measurements specified by the parameter type `Measurement`. Accelerometer Methods ### `addListener(listener)` Supported platforms: Android, iOS, Web. | Parameter | Type | Description | | --- | --- | --- | | `listener` | Listener<[AccelerometerMeasurement](#accelerometermeasurement)\> | A callback that is invoked when an accelerometer update is available. When invoked, the listener is provided a single argument that is an `AccelerometerMeasurement` object. | Subscribe for updates to the accelerometer. Returns: `EventSubscription` A subscription that you can call `remove()` on when you would like to unsubscribe the listener. ### `getListenerCount()` Supported platforms: Android, iOS, Web. Returns the registered listeners count. Returns: `number` ### `getPermissionsAsync()` Supported platforms: Android, iOS, Web. Checks user's permissions for accessing sensor. Returns: `Promise` ### `hasListeners()` Supported platforms: Android, iOS, Web. Returns boolean which signifies if sensor has any listeners registered. Returns: `boolean` ### `isAvailableAsync()` Supported platforms: Android, iOS, Web. > You should always check the sensor availability before attempting to use it. Returns whether the accelerometer is enabled on the device. On mobile web, you must first invoke `Accelerometer.requestPermissionsAsync()` in a user interaction (i.e. touch event) before you can use this module. If the `status` is not equal to `granted` then you should inform the end user that they may have to open settings. On **web** this starts a timer and waits to see if an event is fired. This should predict if the iOS device has the **device orientation** API disabled in **Settings > Safari > Motion & Orientation Access**. Some devices will also not fire if the site isn't hosted with **HTTPS** as `DeviceMotion` is now considered a secure API. There is no formal API for detecting the status of `DeviceMotion` so this API can sometimes be unreliable on web. Returns: `Promise` A promise that resolves to a `boolean` denoting the availability of the accelerometer. ### `removeAllListeners()` Supported platforms: Android, iOS, Web. Removes all registered listeners. Returns: `void` > **Deprecated:** use subscription.remove() instead. ### `removeSubscription(subscription)` Supported platforms: Android, iOS, Web. | Parameter | Type | | --- | --- | | `subscription` | `EventSubscription` | Returns: `void` ### `requestPermissionsAsync()` Supported platforms: Android, iOS, Web. Asks the user to grant permissions for accessing sensor. Returns: `Promise` ### `setUpdateInterval(intervalMs)` Supported platforms: Android, iOS, Web. | Parameter | Type | Description | | --- | --- | --- | | `intervalMs` | `number` | Desired interval in milliseconds between sensor updates. Starting from Android 12 (API level 31), the system has a 200Hz limit for each sensor updates. | Set the sensor update interval. Returns: `void` ## Interfaces ### `Subscription` Supported platforms: Android, iOS, Web. A subscription object that allows to conveniently remove an event listener from the emitter. Subscription Methods ### `remove()` Supported platforms: Android, iOS, Web. Removes an event listener for which the subscription has been created. After calling this function, the listener will no longer receive any events from the emitter. Returns: `void` ## Types ### `AccelerometerMeasurement` Supported platforms: Android, iOS, Web. Each of these keys represents the acceleration along that particular axis in g-force (measured in `g`s). A `g` is a unit of gravitational force equal to that exerted by the earth’s gravitational field (`9.81 m/s^2`). | Property | Type | Description | | --- | --- | --- | | timestamp | `number` | Timestamp of the measurement in seconds. | | x | `number` | Value of `g`s device reported in X axis. | | y | `number` | Value of `g`s device reported in Y axis. | | z | `number` | Value of `g`s device reported in Z axis. | ### `PermissionExpiration` Supported platforms: Android, iOS, Web. Literal Type: `union` Permission expiration time. Currently, all permissions are granted permanently. Acceptable values are: `'never'` | `number` ### `PermissionResponse` Supported platforms: Android, iOS, Web. An object obtained by permissions get and request functions. | Property | Type | Description | | --- | --- | --- | | canAskAgain | `boolean` | Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission. | | expires | `PermissionExpiration` | Determines time when the permission expires. | | granted | `boolean` | A convenience boolean that indicates if the permission is granted. | | status | `PermissionStatus` | Determines the status of the permission. | ## Enums ### `PermissionStatus` Supported platforms: Android, iOS, Web. #### `DENIED` `PermissionStatus.DENIED = "denied"` User has denied the permission. #### `GRANTED` `PermissionStatus.GRANTED = "granted"` User has granted the permission. #### `UNDETERMINED` `PermissionStatus.UNDETERMINED = "undetermined"` User hasn't granted or denied the permission yet. --- --- title: AgeRange description: 一个通过 Android 上的 Play Age Signals API 和 iOS 上的 Declared Age Range 框架提供年龄范围信息访问的库。 sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-age-range' packageName: 'expo-age-range' platforms: ['android', 'ios', 'expo-go'] isAlpha: true --- ## Submitting Feedback If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved: curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/versions/latest/sdk/age-range/","feedback":"🤖 Agent feedback: "}' Only submit when you have something specific and actionable to report. # Expo AgeRange 一个通过 Android 上的 Play Age Signals API 和 iOS 上的 Declared Age Range 框架提供年龄范围信息访问的库。 Android, iOS, Included in Expo Go > For the complete documentation index, see [llms.txt](/llms.txt). Use this Use this file to discover all available pages. > **重要** **此库目前处于 [alpha](/more/release-statuses#alpha) 阶段,并且会频繁出现破坏性变更。** `expo-age-range` 提供对用户年龄范围信息的访问。它在 Android 上使用 Google 的 [Play Age Signals API](https://developer.android.com/google/play/age-signals/use-age-signals-api),在 iOS 上使用 Apple 的 [Declared Age Range framework](https://developer.apple.com/documentation/declaredagerange/)。 此库允许你从应用用户那里请求年龄范围信息,以帮助你遵守适龄内容法规(例如 [美国得克萨斯州](https://developer.apple.com/news/?id=btkirlj8) 的相关要求),并在应用中提供适龄体验。 ### 限制 我们强烈建议在真机上测试该功能,因为模拟器运行时可能无法按预期工作。 ## 安装 ```sh npx expo install expo-age-range ``` If you are installing this in an [existing React Native app](/bare/overview), make sure to [install `expo`](/bare/installing-expo-modules) in your project. ## 在 app 配置中进行配置 ### 设置 iOS 项目 要在 iOS 上使用年龄范围 API,你需要使用 Xcode 26.0 或更高版本构建项目。需要 `com.apple.developer.declared-age-range` entitlement。将其添加到你的 [app config](/versions/latest/config/app) 文件中: ```json { "expo": { "ios": { "entitlements": { "com.apple.developer.declared-age-range": true } } } } ``` Are you using this library in an existing React Native app? 对于现有的 React Native 项目,将该 entitlement 添加到项目的 **ios/[app]/[app].entitlements** 文件中: ```xml com.apple.developer.declared-age-range ``` ## 使用 ```tsx import * as AgeRange from 'expo-age-range'; import { useState } from 'react'; import { StyleSheet, Text, View, Button } from 'react-native'; export default function App() { const [result, setResult] = useState(null); const requestAgeRange = async () => { try { const ageRange = await AgeRange.requestAgeRangeAsync({ threshold1: 10, threshold2: 13, threshold3: 18, }); setResult(ageRange); } catch (error) { setResult({ error: error.message }); } }; return (