Expo SDK 58 beta 发布:iOS 27、Expo Modules 2.0、Rust 版打包器
SDK 58 beta 带来 iOS 27 与液态玻璃适配、Expo Modules 2.0、冷启动打包快约两倍的 Rust 转换器,以及一批破坏性变更;Expo Go 暂时只能通过 CLI 安装。
中文
复制

SDK 58 beta 期从今天开始,持续三到四周。 beta 期是给开发者试用、确认新版本没有在自己的系统和应用配置上引入回归的窗口。期间我们会持续发布修复和改进。
SDK 58 是为 iOS 27 构建的,如果你现在就需要 iOS 27 支持,可以直接用 beta 版发版。SDK 58 beta 包含 React Native 0.88(Release Candidate):0.88 还没正式发布,所以 beta 用的是 RC;0.88 一正式发布,我们就会切到稳定版,并在之后不久发布 SDK 58。SDK 58 的完整 release notes 要等到稳定版才会出,但你现在就可以翻 expo/expo 仓库里的各个 changelog,了解这次发布的规模与破坏性变更。beta 结束时我们会把全部 changelog 合并进根目录的 CHANGELOG.md。
SDK 58 的 Expo Go 目前只能通过 Expo CLI 安装,支持 Android 设备与模拟器、iOS 模拟器;iOS 真机走 eas go(更多说明)。App Store 与 Google Play 上的 Expo Go 会在稳定版发布后不久更新到 SDK 58,所以你有时间在商店版砍掉 SDK 57 支持之前升级。
我们还会在 Discord 上开设 office hours,欢迎想帮忙测试这次发布的人参加。
SDK 58 为 iOS 27 构建
iOS 27 要求使用 UIKit 的 scene 生命周期,并让 iPhone 应用可缩放;用 iOS 27 SDK 构建的应用会自动获得这两点。Expo 应用现在改用 scene 生命周期,以便在 iOS 27 上正确启动(#46733)。这会改变 app delegate 回调的投递方式,如果你自定义了 AppDelegate.swift,请读scene 生命周期迁移指南。Expo 各个包不再从 UIScreen.main 读取几何信息(#48172、#48315、#48316、#48170、#48169),expo-modules-core 也提供了感知 scene 的几何工具(#48168)。
在 iOS 27 上,requireFullScreen 不再能让你的应用退出缩放,应用可缩放时 ScreenOrientation.lockAsync 可能完全不起作用。requireFullScreen 配置插件已为此更新(#48175)。参见 iOS 27 及之后的屏幕方向锁定。用 iOS 27 SDK 构建的应用里,expo-glass-effect 会把 isLiquidGlassAvailable 报为 true(#49850)。
beta 期间我们还会持续改进,确保 iPhone Duo SDK 一开放给开发者,就能从第一天起做到深度集成。
带 Xcode 27 和 SDK 58 工具链的 EAS Build 镜像很快会推出,可用之后我们会更新这篇文章;在那之前,latest 这个 EAS Build 镜像带的是 Xcode 26.6。
支持 Xcode 27 的 Device Hub
Xcode 27 用 Device Hub 取代了 Simulator.app。Expo CLI 会识别 Device Hub,通过它启动模拟器,并用 devices:// 深链聚焦到指定设备(#46757、#46809)。如果你不想离开编辑器,新的 expo-device-hub 开发工具插件能把浏览器变成一台本地设备面板:所有 iOS 模拟器和 Android 模拟器的实时画面,可以直接点按、滑动、输入,还带启动/关机控制、CPU/内存/网络曲线,以及外观、Liquid Glass、字号、无障碍设置等开关。装上它(npx expo install expo-device-hub)再跑 npx expo start,终端里就会打印链接。如果你想要同样的体验但本机没有 Xcode 或 Android Studio,可以关注 EAS Simulator——我们即将推出的云模拟器服务。

App Intents:把应用暴露给 Siri 与 Apple Intelligence
expo-app-intents 让 Expo 应用可以声明 Apple App Intents(Siri、快捷指令、Spotlight 与 Apple Intelligence)(#47207)。App Intent 类型写在 app-intents 目录下的 Swift inline module 里,因为 Apple 在构建期提取元数据时只能看到 app target 内的代码。这个包会把调用投递给 JavaScript,并保存 entity 值。运行 npx expo-app-intents init 来创建该目录(#47223)。这个库还在 alpha,文档和示例随后补齐。
例子:用 Siri 完成一项任务
一个 onboarding 清单应用声明了「完成任务」这个 intent 和一个任务 entity。你对 Siri 说要完成某项任务,Siri 会列出应用里的任务并问你选哪个;选一个,intent 就在你的 JavaScript 里运行,应用把它标记为完成——全程不需要把应用拉到前台。

Expo UI:iOS 上的原生导航、新的 Compose 组件,还有更多
每个组件在文档里都有预览图
Expo UI 参考文档现在在每个组件的 API 旁边放了一张截图,让你在读 props 之前就看清自己选的是什么。可以浏览文档里的 SwiftUI 和 Jetpack Compose 画廊。

iOS 导航。 @expo/ui 新增 NavigationStack、Toolbar、NavigationLink、NavigationDestination 组件,navigationTitle 修饰符,以及 close 按钮角色(#49940、#49991)。NavigationSplitView 增加了两栏和三栏布局(#50075)。
SwiftUI。 background、tint、border、strokeBorder、containerBackground、presentationBackground 和 foregroundStyle 这些修饰符现在接受任意 ShapeStyle,所以视图可以用材质或渐变来上色(#48905、#49621、#49767、#49838)。新增的还有 Background 组件(#48904),以及 scrollClipDisabled(#49780)、geometryGroup(#48838)、listRowSeparatorTint(#48810)、alignmentGuide(#49247)、menuStyle 与 menuIndicator(#48448)修饰符。
Jetpack Compose。 新增 Image(#48521)、DateRangePicker、DateRangePickerDialog(#49788)和 VerticalSlider(#49612)组件。DropdownMenu 增加 cornerRadius 和 shadowElevation(#49515、#49896),RadioButton 增加 enabled 和 colors(#49852)。
通用组件。 BottomSheet 增加 contentPadding、containerColor 和 contentColor,ListItem 支持 colors(#48902、#49575)。Web 上,BottomSheet 去掉了不再维护的 vaul,改用自研的 HTML <dialog>(#49509)。
托管 React Native 视图。 放在 <RNHostView> 里的视图现在按 SwiftUI 和 Jetpack Compose 摆放它们的位置来测量(#48969、#48970)。这修好了点按丢失、手势被外层滚动容器抢走,以及 BottomSheet、Popover、AlertDialog、DropdownMenu 内部点不到的问题。现在点托管文本框外部会收起键盘(#48788)。关闭 SwiftUI Menu 的那一次点击也不再会按下它下面的 React Native 视图(#48463、#49775)。
Expo 与 EAS Observe
EAS Observe 用来监控生产环境里应用的性能与错误,8 月 20 日起已正式可用。SDK 58 里 expo-observe 新增 Observe.registerIntegration(#48245)、ObserveErrorBoundary 与 reportError(#47341、#47871)、errorHandlingEnabled 选项(#48506)、一个 expo-image 集成(#47145),以及 Observe.clientId——记在每个事件上的 EAS client ID(#49599)。AppMetrics 已废弃,改用 Observe——见废弃项。

@expo/agent-cli:给 agent 设计的新 CLI
过去 agent 学 Expo 都是硬啃:启动 Expo Go,加一个 Expo Go 不支持的 native module 就撞运行时错误,然后自己猜该用 development build;还得知道什么时候该用 Expo CLI、什么时候该用 EAS CLI。@expo/agent-cli 是一个新的实验性 CLI,由 agent 构建、为 agent 设计。它架在 Expo CLI、EAS CLI 和 expo-doctor 之上,并且会回落到 Expo CLI,所以你可以直接让 agent 用它替代原来的工具。
可以试试几个有用的命令:status 不用启动应用就能回答 Expo Go 兼容性;dev 一条命令把应用跑起来,类似 web 框架同时起服务端和浏览器,它自己判断什么时候需要构建,并尝试用最快的方式让应用跑起来;命令会打印下一步该做什么,agent 就知道怎么往下走。smoke 等于 dev 加截图加停止,用来确认你这台机器上确实能开始开发。skills:sync 会把 node_modules 里同位置的 agent skills 装到你的项目里。
从 npx @expo/agent-cli@latest agents:setup 开始,然后让你的 agent 用 @expo/agent-cli 替代 Expo CLI。
想要更短的名字,expo-agent-cli 是一个别名。感谢 Kazutoyo Tokai 把这个包名转给我们。这个 CLI 还在积极开发中,之后会有一篇博客展开讲;在那之前,先试试,也欢迎告诉我们你的想法。
主屏小组件来到 Android
expo-widgets 增加了 Android 实现:小组件在专用的 Hermes 运行时里跑自己的 JS bundle,支持交互和 Material Colors(#46961、#47035、#48454)。iOS 上,Live Activities 的 LiveActivity.start() 和 update() 增加 staleDate 选项(#46343),ActivityKit 标识符变稳定(#48589),小组件配置支持运行时变更(#47533)。
Swift Package Manager 构建
React Native 0.87 加入了实验性的 Swift Package Manager 支持,作为 CocoaPods 之外的另一个选项,SDK 58 为 Expo 应用铺好了路。Expo 的 iOS 源码已经重构,Swift、Objective-C 和 C++ 会分别编译成独立的 SwiftPM target(#45906、#49820、#49821、#49832),给 React Native npx react-native spm 流水线用的 Expo autolinking 插件正在 review 中(#49823),我们计划在 beta 期间以预览形式发布。CocoaPods 仍是默认且受支持的路径,预编译的 Expo module 在那里照常工作。
Expo Modules:更快的构建、更快的调用、更简单的写法
用预编译的 expo-modules-core 加速 Android 构建
expo-modules-core 现在为 Android 提供预编译好的原生库。以前每一次干净构建、每一次 CI、每一次 EAS Build 都要从源码编译 libexpo-modules-core.so 里的 C++,这是使用 Expo 的 Android 构建中最贵的一步。现在 npm 包里包含全部四个 ABI 的 .so 文件,debug 与 release 变体都有。我们在一个空白 SDK 58 项目上测:四个 ABI 的 Android debug 干净构建在 Apple M3 Pro 上约 80 秒,跳过 expo-modules-core 的 C++ 编译后降到约 39 秒,差不多一半。核数少的机器(比如 CI runner)省得更多。被省掉的编译工作量在四个 ABI 上累计超过 10 分钟,12 核机器靠并行跑很多文件把它隐藏了。
更快的 Expo 模块
一次 native module 调用不是免费的:跨进 Swift 或 Kotlin、再转换两个方向上的值,都有固定开销,而那些便宜的调用里大部分成本就花在这里。SDK 56 在两个平台上都动过这块:iOS 上去掉了 Objective-C++ 层,调用快了 1.6 到 2.3 倍;Android 上用 Kotlin 编译器插件取代反射,Record 转换快了约 6 倍,首屏渲染时间缩短约 30%。
SDK 58 又在 iOS 这侧推了一轮。传递或返回简单值的调用更便宜了(#49761),两个方向上传递长字符串最多快 3.8 倍(#49678),async 函数返回的 promise 创建与 resolve 的开销也更低(#49718)。不需要你做任何接入:升到 SDK 58,所有 Expo module 都会变快,包括不是你写的那些。
Expo Modules 2.0 beta
另一半故事是你写代码时对着的那套 API。你现在不用在既有的 DSL 定义里描述 native module,而是可以直接写一个普通的 Swift 或 Kotlin 类,把想暴露给 JavaScript 的方法和属性加上注解。除了这几个注解没有新东西要学,对编码 agent 也更友好——不需要先解释一套自定义 DSL,就是 Swift 和 Kotlin,模型本来就很熟。
在以上改进之上它还更快:注解让我们在构建期生成最直接的 binding,而不是运行期现找。同一个 SDK 上,用 iPhone 16 Pro 的 Release 构建测量,同步调用比 DSL 快 2.5 到 5.6 倍。Expo Modules 2.0 抢先看里有基准数据,也更深入地讲了这套 API。
Android 上 Kotlin 侧呈现同样的模式,这次我们还拿 React Native 的 TurboModules 做了对照。十二项微基准里,Expo Modules 2.0 每一项都快过 Expo Modules 1.0,从传 100 个数字数组的 1.2 倍,到发一个带数字的事件快 39.9 倍。它同样每一项都快过 TurboModule:无参数调用 112 ns 对 2,837 ns,传 20 个对象数组 10.7 µs 对 149.8 µs,发一个带对象的事件 963 ns 对 8,080 ns。

SDK 57 把 iOS 宏作为实验发布;到 SDK 58 beta,Expo Modules 2.0 在 iOS 和 Android 上都进入 beta。文档会在 beta 期间补齐,在那之前抢先看那篇博客是最好的指引。
新的 fingerprint 默认值:少了不必要的原生重构建
改个版本号、或者动了 node_modules 里的文件,不再意味着 fingerprint 变化。SDK 58 把 fingerprint 的默认值改成 balanced 预设(#47668)。它会忽略更新 app.json 里的 version 这类常见情况,并且按包名和版本(而不是文件与目录)来为 native module 计算哈希。不需要额外配置,哈希就保持稳定。如果你想要不同的取舍,可以看fingerprint 预设。
实验性:用 Rust 写的转换器把冷启动打包提速约 2 倍
Metro 的缓存让热打包很快,但冷打包——无论整个项目还是改动过的模块——大部分时间都花在 Babel 上。SDK 58 引入一个实验性替代品:“Noxcturnal”,一个用 Rust 写的 module transformer,基于 oxc,通过 napi-rs 暴露给 Node.js。在我们的内部测试里,单模块转换时间约快 3 倍,端到端冷打包约快 2 倍(#48443)。在我们最大的测试应用上,约 5,500 个文件的冷打包从 Babel 的 5.26 秒降到新转换器的 2.46 秒,其中仍有 443 个文件回落到 Babel。

在 app config 里设置 experiments.noxcturnalTransformWorker 就能试用。只有当你的项目没有自定义 transform worker 或 Babel 插件/预设时它才会生效,并且会跳过需要 Reanimated 或 Worklets Babel transform 的文件。这还是很早期的工作:实现和数字在稳定之前都可能变,我们计划加上配置项,让更多项目(包括带自定义 Babel transform 的)也能用上。
Expo Router:数据加载器与原生标签稳定,导航核心改进
数据加载器、服务端渲染和中间件现在都是稳定功能,不再需要实验开关。原生标签、工具栏和标准导航集成也已稳定。
Expo Router 的导航核心也重写了,导航状态变得确定、更容易推理,并且不再携带大部分 fork 出来的 React Navigation API。多数应用不会察觉。但如果你写过自定义 navigator,或者从 expo-router/react-navigation 导入,有些 API 已经迁移或移除;如果你需要的某一个不见了,请开 issue说明你想做什么。
其他改动列在下面,文档链接我们会陆续补上。
-
Navigator 迁移:JavaScript 的
Tabs、TopTabs、Drawer现在和NativeTabs使用同一套standard-navigation集成,行为更一致。 -
Loader 缓存:在
loader里从expo-server调用setResponseHeaders({ 'Cache-Control': 'private, max-age=60' }),就能让客户端把它的响应缓存 60 秒。 -
React transitions 与 Activity:导航使用 React transitions,在下一个屏幕加载时保持当前屏幕可见。在 navigator 或 screen 上设置
activityEnabled,或者用NavigationAwareActivity包住屏幕的一部分,就能在保留状态、清理 effect 的同时隐藏非活跃内容。 -
Web 上默认开启异步路由:
expo-router配置插件现在自动为 web 启用asyncRoutes。路由文件会被拆成独立的 JavaScript chunk,浏览器导航到该路由时再加载。设置asyncRoutes: { web: false }可以关掉。 -
自定义 router API:用
extendRouter覆盖内置 router 的一部分,或用extendRouterActions为自定义导航动作添加 handler。 -
屏幕级错误边界:在 layout 里设置
unstable_settings.screenErrorBoundary,或者传<Stack unstable_screenErrorBoundary={MyErrorBoundary} />,就能为抛错的屏幕显示兜底 UI,同时保持 navigator 挂载。 -
可选依赖:Android 上,要用带
mdprop 的NativeTabs.Trigger.Icon需要安装expo-symbols,要用Stack.Toolbar需要@expo/ui。这两个包现在是可选 peer 依赖。
升级时请读迁移指南,如果你用了自定义 navigator 或从 expo-router/react-navigation 导入,尤其要读。
通过代理和隧道连接 dev server
如果你的 dev server 跑在代理后面、远程机器上,或者通过隧道暴露,development build 现在应该能稳定连上它。以前 development build 启动时拉取的 manifest 会告诉它用哪个 bundle URL 和 debugger hostname,而当服务端在代理后面、或者通过 Bonjour 被发现时,那些地址可能是客户端根本连不到的。现在只要客户端支持,manifest 就用相对 URL(#47255、#48997)。
RCT_METRO_PORT 在预编译的 React Native 里是一个编译期宏,被冻在 8081,所以没有 expo-dev-client 的 bare 应用永远只跟 8081 对话,两个这样的应用同时跑会互相响应对方的 reload 命令。现在 prebuild 会把端口写进 Info.plist 的 RCTMetroPort 键,应用在启动时读取它(#48098)。Expo CLI 的端口选择也更一致了,非交互运行时不再直接失败,而是顺延到下一个空闲端口(#47771、#48300)。
更快、更可靠的 Expo CLI 隧道
Expo CLI 有了基于 @expo/ws-tunnel 2.0 的新隧道实现(#46696)。它连接更快、连接更稳定,也不再需要 @expo/ngrok。这样试:
EXPO_UNSTABLE_TUNNEL_V2=1 expo start --tunnel
使用它需要登录你的 Expo 账号(expo login)。
EXPO_UNSTABLE_TUNNEL_V2 开关会在 SDK 58 beta 后期去掉,届时这会成为默认的隧道实现。
React Native 0.88(Release Candidate)
SDK 58 beta 把 React Native 从 0.86 升到 0.88 release candidate,所以它同时吸收了 React Native 0.87 和 React Native 0.88 release candidate 的改动。0.88 的要点包括:
-
Swift Package Manager 工具:可选的
npx react-native spm命令和 SwiftPM 包生成。CocoaPods 仍是默认且受支持的路径。 -
Text上的fontVariationSettings:用对象语法设置可变字体轴,和这个版本里expo-font加入的可变字体支持正好搭配。 -
TurboModules 里的
ArrayBuffer:JavaScript 的ArrayBuffer值现在在 Android 和 iOS 上都有原生表示,并带一份明确的字节所有权约定。 -
React Native DevTools:实验性的性能截图,以及 Network 面板里的 WebSocket 检查。
完整情况请看 React Native 0.87 release notes 和 React Native 0.88.0-rc.0 release notes。等 React Native 0.88 的博客发布后,我们会在这里补上链接。
PostHog 集成
现在一条命令就能在 Expo 应用里接好 PostHog,而且它捕获的每个事件都知道自己来自哪次 EAS update。运行 eas integrations:posthog:connect,EAS CLI 会创建或关联你的 PostHog 项目、安装 SDK 及其配置插件,并把环境变量写进你的项目和 EAS。PostHog 能识别 eas/update_id、eas/build_id、eas/channel 和 eas/runtime_version 这些属性,并把它们关联回 expo.dev。这是 EAS CLI 的能力,所以任何 SDK 版本都能用。可以读 PostHog 集成 changelog 和使用 PostHog 指南。
其他值得注意的改动
-
expo-camera:新增CameraView.scanDocumentAsync,在 Android 和 iOS 上做多页文档扫描(#47362)。 -
expo-file-system:新增File.digest(),支持 MD5/SHA-1/SHA-256/SHA-384/SHA-512 哈希(#48089),以及用于原生预览流程的File.preview()和File.canPreview()。 -
expo-audio:新增带播放列表的锁屏控制(#46020),以及用AudioStream.startFileRecordingAsync录制 WAV/PCM 文件(#46771)。 -
expo-image:新增transition.skipOnCacheHit,命中缓存时跳过转场(#48181);以及svgVariablesprop,为 SVG 里用var()引用的 CSS 自定义属性替换取值,于是同一份文档的不同部分可以给不同颜色,而图片仍然是矢量(#48663)。取值不限于颜色。用var()的 SVG 现在即使不传这个 prop,也会用回退值渲染。 -
expo-secure-store:Android 上新增requireConfirmation,用于需要认证的读写(#48556)。 -
expo-dev-launcher:新增disableFab=1与disableAutoLaunch=1两个 URL 参数,用来隐藏浮动按钮、并阻止 dev menu 在启动时自动打开(#49651)。 -
expo:URL和URLSearchParams重写,支持 IDNA/TR-46(#47813),TextDecoder为速度重写(#48877)。 -
expo-sqlite:自带一份同位置的 agent skill,把最佳实践分享给 agent。运行npx @expo/agent-cli skills:sync就能装进你的项目(#49867)。 -
expo-font:在 Android、iOS 和 web 上支持可变字体,一个字体文件就能提供一个包含多个字重或字形的 family。useFonts、loadAsync和配置插件都能用(#48129、#48621、#48432、#49486、#49487、#49485)。了解更多。 -
expo-notifications:iOS 上,通知中心的调用会转发给另一个库注册的UNUserNotificationCenterDelegate,所以expo-notifications可以和别的推送库共存于同一个应用(#48313),通知也可以用threadIdentifier分组(#49429)。Android 上,日期与重复触发器新增delivery: 'alarmClock'选项,使用AlarmManager.setAlarmClock()——OEM 的省电策略不会推迟它——用于对时间敏感闹钟(#49687),配置插件新增largeIcon属性(#49481)。了解更多。 -
expo-location:我们正在围绕一层位置提供者抽象重写expo-location,带来更简单的定位 API、位置监听、后台位置更新,以及请求 iOS 临时全精度等新权限选项(#49849、#49972、#49988)。这次重写会以可选预览的形式和现有 API 并存,所以这个 beta 里现有的expo-location代码什么都不用改。可以试的时候我们再细说。 -
@expo/cli:Android 虚拟设备(AVD)与adb管理重写,对失败更有韧性(#49258)。
废弃项
-
expo-file-system:File.md5废弃,改用File.digest()(#48089)。 -
expo-modules-core:NativeArrayBuffer废弃,改用ArrayBuffer(#47106)。 -
expo-observe:AppMetrics导出废弃,改用Observe(#48901)。 -
expo-sqlite:useLibSQL配置插件属性废弃,且不再有任何效果(#48543)。 -
@expo/ui:iOS 上backgroundOverlay废弃,改用background(#49621);border与strokeBorder的color参数废弃,改用content(#49838)。
值得注意的破坏性变更
-
React Native 严格 TypeScript API:React Native 0.87 把严格 TypeScript API 变成默认。从
react-native/Libraries/*深层导入现在会报类型错误,部分类型形状也变了,最明显的是 ref,现在使用ViewInstance、TextInputInstance这类实例类型。可以按迁移指南做,也可以交给 agent,用 migrate-to-strict-api skill。想推迟迁移,就在 tsconfig.json 里设置"customConditions": ["react-native", "react-native-legacy-deep-imports"](保留"react-native",expo/tsconfig.base已经设置过)。这个退出开关在 React Native 0.88 之后会被移除,所以计划在 SDK 58 周期内完成迁移。 -
React Native API 移除:
InteractionManager(改用requestIdleCallback)、Touchable根导出、NativeMethods类型、Modal的animatedprop,以及已废弃的StatusBar的backgroundColor、translucent、networkActivityIndicatorVisible都被移除。ImageBackground废弃,改用View里放一个绝对定位的Image。完整列表见 0.87 与 0.88.0-rc.0 的 release notes。 -
iOS 的 scene 生命周期:iOS 27 SDK 要求 UIScene 生命周期,所以
npx expo prebuild现在会生成 SceneDelegate.swift 和 Info.plist 里的UIApplicationSceneManifest条目,UIWindow由 scene delegate 创建,而不再在didFinishLaunchingWithOptions里(#46733、#46734)。Expo 会把 URL、user activity、Handoff、生命周期和快捷动作事件转发给ExpoAppDelegate的覆写与订阅者,所以基于这些的配置插件和模块照常工作(#49925、#50032)。如果你手工管理 ios 目录、用的是 bare React Native 应用,或者直接覆写 app delegate 方法,请看迁移指南。 -
NODE_ENV与环境文件:现在每条 Expo CLI 命令都会在加载 .env 文件和 app config 之前把NODE_ENV设为development或production,所以动态的 app.config.js 和 .env 级联在模式上始终一致(#48554、#48741、#48839)。以前每条命令都会保留继承来的NODE_ENV,而expo config干脆不设置,于是NODE_ENV=test npx expo start会加载 .env.test。现在继承来的值会被忽略,该命令加载的是 .env.development。Jest 在你的测试里仍然设置NODE_ENV=test,@expo/env在那里仍然解析 .env.test.local、.env.test 和 .env。参见环境变量指南。 -
Android 应用模板:release 构建现在默认通过 gradle.properties 里的
android.enableMinifyInReleaseBuilds=true启用 R8(#50108)。R8 会缩减、优化并混淆 Java/Kotlin 代码,从而减小包体、改善启动时间;应用使用proguard-android-optimize.txt预设优化。依赖反射的库可能需要 ProGuard keep 规则。想关掉,就用expo-build-properties把android.enableMinifyInReleaseBuilds设为false。 -
expo-router:导航核心的改动让导航状态和 route key 变得确定,把导航派发推迟到 commit 之后,并移除了相当一部分 fork 出来的 react-navigation API。@expo/ui与expo-symbols现在是可选 peer 依赖。迁移指南逐条覆盖,完整列表在 expo-router changelog。 -
expo-file-system:File.write()现在是异步的并返回 promise;想要原来的行为请用File.writeSync()(#45992)。 -
expo-sqlite:移除 libSQL 支持——syncLibSQL()和libSQLOptions都没了(#48543)。 -
expo-notifications:前台通知现在默认展示,除非你的setNotificationHandler另有指示;handler 慢也不再丢通知(#49072)。这次发布里expo-notifications的其他改动见其他值得注意的改动。 -
@expo/fingerprint:默认预设现在是balanced(#47668)。 -
@expo/ui:iOS 上<Host>改为顶部对齐而非居中,于是flex: 1的 host 和 Android 一致(#47561)。HStack、VStack和GlassEffectContainer现在把未设置的spacing作为nil转发给 SwiftUI,使用系统默认间距;传spacing={0}保持原来的布局(#48441)。Android 上RNHostView的styleprop 被移除,改用modifiers(#48970)。 -
expo-localization:iOS 上不再通过supportsRTL依据设备语言强制开启 RTL;布局方向跟随I18nManager(#48086)。 -
expo-media-library:iOS 上Asset.getUri()和AssetInfo.uri现在解析视频在 Photos 里的当前版本;想要原来的行为请传version: AssetUriVersion.ORIGINAL(#48640)。 -
@expo/cli:expo login现在默认走浏览器登录;想要原来的行为请用--no-browser或--username/--password(#46832)。
工具版本要求
-
Node.js:Expo 工具链现在要求 Node.js 22 系列至少 22.13、24 系列至少 24.3,或者 Node.js 26 及以上。23、25 这类奇数版本不受支持(#47202)。
-
Android Gradle Plugin:Expo modules 工具链现在兼容 AGP 9(#46766、#46769)。
已知回归
- 目前没有报告。beta 期间有新的发现,我们会更新这一节。
怎么试用这个 beta 版
用 SDK 58 beta 初始化新项目
# npm
npx create-expo-app@latest --template default@next
# bun
bun create expo-app --template default@next
# pnpm
pnpm create expo-app --template default@next
# yarn
yarn create expo-app --template default@next
注意:create-expo-app 会用你正在使用的包管理器安装依赖。比如用 npx 时就是 npm,用 yarn create 时就是 yarn。
升级已有项目
可以配合 Claude Code 用我们的 expo-upgrade skill 把应用升到 beta。你遇到任何问题都欢迎反馈,我们会在接下来几周继续打磨它。
下面是手动升级的步骤。
- 把所有依赖升到与 SDK 58 匹配:
npx expo install expo@next --fix
- 读 SDK 58 文档,获取完整 API 参考。
该测什么
-
升级并测试:运行
npx expo install expo@next --fix,然后对照原生项目升级助手,并报告你遇到的问题。 -
原生构建:用 EAS Build 构建(带 Xcode 27 与 SDK 58 的镜像很快推出,见上文);如果你本地装了 Xcode 和 Android Studio,也可以试试 prebuild 再运行:
npx expo prebuild --clean、npm run ios、npm run android。或者试试npx expo run。遇到新问题?请报告给我们。 -
发现文档缺口?告诉我们。
怎么报问题
感谢你测试 beta,非常感谢!