Expo 框架深度指南:用一套 React 代码库构建 Android、iOS 与 Web 通用原生应用

发布时间:2026/9/25 15:21:42
Expo 框架深度指南:用一套 React 代码库构建 Android、iOS 与 Web 通用原生应用
Expo 框架深度指南用一套 React 代码库构建 Android、iOS 与 Web 通用原生应用【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expoExpo 是官方推荐的用于构建生产级 React Native 应用的开源框架其目标是用单一 TypeScript/JavaScript 代码库同时交付 Android、iOS 与 Web 三端原生应用。本文以当前仓库中expo包SDK 版本 57.0.9见 packages/expo/package.json为对象完整梳理其快速上手的标准流程、核心生态组件Expo SDK、Expo Router、Expo Modules API、Expo UI、DOM 组件、持续原生生成与 EAS并结合packages/expo源码中的入口实现、模块导出与 Web 标准 polyfill讲清楚 Expo 包本身在运行时到底做了什么。读完你将掌握如何创建并启动一个 Expo 项目、如何将 Expo 集成进既有 React Native 工程、expo包的运行时入口与核心导出 API以及 SDK 中各模块的版本对齐与按需安装机制。快速开始从零创建并启动一个 Expo 应用Expo 的官方快速启动路径围绕create-expo-app与expo start两个命令展开README 给出的标准流程为npx create-expo-applatest my-app cd my-app npx expo startnpx create-expo-applatest my-app在当前目录下创建名为my-app的新项目。该脚手架工具的本体位于 packages/create-expo/其src目录中实现了模板选择、依赖安装与初始化逻辑仓库同时内置了expo-template-default、expo-template-blank、expo-template-blank-typescript、expo-template-tabs、expo-template-bare-minimum等多套模板见 templates/其中expo-template-default已默认集成 Expo Router 与 TypeScript。npx expo start启动由 Metro 驱动的开发服务器提供 Fast Refresh快速刷新、按平台一致的开发体验并输出二维码供真机扫码。启动后你可以在模拟器、安装了 Expo Go 的真机或 Web 浏览器中打开应用。既有 React Native 工程接入 Expo如果你已经有一个纯 React Native 工程不必迁移重写直接在项目根目录执行npx install-expo-moduleslatest该命令的本体位于 packages/install-expo-modules/它会自动完成原生依赖注入、配置文件生成等迁移工作让既有工程获得 Expo 模块体系autolinking与工具链支持。入口文件的运行时约定Expo 包自带了默认的 App 注册入口 packages/expo/AppEntry.js其实现极为精简import registerRootComponent from expo/src/launch/registerRootComponent; import App from ../../App; registerRootComponent(App);它把工程根目录的App组件交给registerRootComponent注册为原生根视图。如果不想使用默认入口也可在自己的入口中直接调用registerRootComponent(YourApp)该 API 由 packages/expo/src/Expo.ts 从./launch/registerRootComponent导出。registerRootComponent的完整实现位于 packages/expo/src/launch/registerRootComponent.tsx它做了四件事在非生产环境下用withDevTools包装组件注入 Fast Refresh 与分包指示器withDevTools.ios.tsx、withDevTools.web.tsx等平台变体见 packages/expo/src/launch/调用 React Native 的AppRegistry.registerComponent(main, ...)注册根组件供 Android、iOS、tvOS 原生侧加载在 Web 端Platform.OS web且存在window查找idroot的 DOM 节点并调用AppRegistry.runApplication完成渲染同时支持__EXPO_ROUTER_HYDRATE__标记下的 SSR 水合hydration在开发模式下全局 polyfillprocess.nextTick。与之配套packages/expo/src/Expo.fx.tsx 是expo包的副作用加载模块它按顺序完成加载 Winter 运行时与 async-require 机制、提前导入expo-asset以注入自定义sourcetransformer、导入expo/virtual/rsc、在 Expo Go / dev-client 环境中优化错误信息与 LogBox 告警并在非生产环境预注册一个AppEntryNotFound占位组件用于提示入口缺失。这些初始化代码构成了import expo时真正执行的第一段逻辑。Expo 生态全景每一块都可以独立使用README 强调Expo 是一组彼此独立可用的工具与服务的集合。下面逐一说明各组成部分及其在当前仓库中的落点。Expo SDK按需安装、完全类型化的原生模块库Expo SDK 提供大量官方维护的跨平台模块覆盖设备 API、媒体、存储与系统服务例如expo-camera、expo-image、expo-notifications、expo-file-system、expo-sqlite、expo-sensors等这些包的源码都位于 packages/ 下如 packages/expo-camera/、packages/expo-sqlite/。所有模块遵循三个原则按需引入opt-in只安装你需要的模块最终 JS bundle 大小与应用实际需求成正比完全类型化每个包都发布配套的.d.ts类型声明版本对齐使用npx expo install安装依赖该命令会读取 packages/expo/bundledNativeModules.json 中记录的与当前 SDK 版本匹配的依赖版本映射表例如expo-camera为~57.0.3、expo-sqlite与 SDK 主版本对齐避免手动挑选版本导致的原生侧 ABI 不兼容。从源码看expo包本体在 packages/expo/expo-module.config.json 中声明了自身仅包含一个原生模块ExpoFetchModuleiOS 端Expo.podspec、Android 端expo.modules.fetch.ExpoFetchModule因此expo包自身很轻绝大多数能力以独立子包形式提供。Expo Router文件即路由的通用导航方案Expo Router 是基于文件的通用路由器file-based router适用于 Android、iOS、Web 三端在app/目录下放入一个文件即得到一个路由自动生成类型化路径typed routes、深链deep linking与 universal link 配置布局layouts、模态框modals、标签页tabs与堆栈stacks都以 React 组件方式组合且在各平台表现一致底层基于react-native-screens提供移动端真正的原生导航器Web 端则使用真实路由器额外提供全栈能力API Routes服务端路由与静态渲染static rendering用于构建对 SEO 友好的 Web 构建产物。路由器的源码位于 packages/expo-router/仓库中的apps/router-tester见 apps/router-tester/app/含 111 个.tsx路由文件与apps/router-e2e见 apps/router-e2e/e2e/是围绕 Router 构建的深度测试应用可用作学习文件路由、嵌套布局与动态路由的真实样例。Expo Modules APISwift/Kotlin 声明式编写原生模块Expo Modules API 是编写原生模块的现代方案也是整个 Expo SDK 及大量第三方库的基础其运行时核心在 packages/expo-modules-core/用小型 Swift 或 Kotlin DSL声明式描述函数、属性、原生视图与生命周期事件框架自动处理 JavaScript 与原生之间的类型转换与调用桥接无需手写 Objective-C、Java、C、JNI 或样板代码通过npx create-expo-modulelatest可在几秒内搭建一个新模块脚手架脚手架实现见 packages/create-expo-module/src/发布为普通 npm 包后会被 iOS/Android 的autolinking机制自动发现并接入autolinking 实现见 packages/expo-modules-autolinking/。仓库内的expo-age-range、expo-app-integrity等新式模块如 packages/expo-age-range/每个都包含android/的 Kotlin 与ios/的 Swift 实现及expo-module.config.json是这一 API 的实际产物样本。Expo UISwiftUI / Jetpack Compose 真原生组件Expo UI含 230 个.tsx、142 个.swift与 80 个.kt文件。你可以在 React 中直接使用系统的选择器picker、开关switch、滑块slider、菜单menu等控件其观感与操作体验与操作系统原生控件完全一致。DOM 组件把 Web 内容渲染进原生应用给 React 组件加上use dom指令Expo 就会把它作为 Web 内容渲染进原生应用内部——非常适合渐进式迁移既有 Web 代码或在移动端复用 React Web 组件。相关运行时入口见 packages/expo/src/dom/expo/dom子路径导出底层 WebView 支持由 packages/expo/dom-webview/ 提供。持续原生生成CNG不再手工维护 ios/ 与 android/Expo 的关键理念之一是ios/与android/目录是生成出来的而不是维护出来的在app.json与 config plugins配置插件中声明原生配置运行npx expo prebuild按需生成原生工程之后的 SDK 升级、新增包、原生定制全部走同一条声明式流水线避免原生代码中的合并冲突。Config Plugins 的实现见 packages/expo/config-plugins/prebuild 逻辑位于 packages/expo/cli/。EAS从 git push 到应用商店的最快路径EASExpo Application Services是托管式的应用发布基础设施覆盖发布全流程EAS Build云端构建 iOS 与 Android 包本地无需安装 Xcode 或 Android StudioEAS Submit一条命令提交到 App Store 与 Play StoreEAS UpdateOTA 推送 JavaScript 与资源更新支持渠道channels与回滚rollbacksEAS Workflows面向构建、测试与发布的 CI/CDEAS Hosting在 Expo 的边缘网络托管 Web 应用与 API RoutesExpo Launch基于浏览器的引导式发布路径无需触碰配置即可上架 Web 与 App Store。EAS 是可选项但对大多数团队而言是从git push到商店的最快路径。仓库中的apps/eas-expo-go与apps/expo-workflow-testing其 eas.json是 EAS 配置的真实示例。工具链CLI、Expo Go、Atlas 与 SnackExpo CLI围绕 Metro 与原生工具链Xcode、Simulator.app、Android Studio、ADB 等的统一命令行入口。expo包在 packages/expo/package.json 的bin字段中暴露了三个可执行文件expo指向bin/cli、expo-modules-autolinking指向bin/autolinking与fingerprint指向bin/fingerprintCLI 本体在 packages/expo/cli/。Expo Go与development builds在真机上数秒内预览应用Expo Go 的完整宿主工程见 apps/expo-go/。Expo Atlas可视化 bundle 分析器检查 JS 中实际打进了什么。Snack在浏览器中零安装体验 Expo。expo包运行时核心导出与 Web 标准补全expo包源码入口 packages/expo/src/Expo.ts是 SDK 的门面它从expo-modules-core中转导出大量核心 API同时提供自己的启动与工具函数。开发者日常最常用的导出包括启动与生命周期registerRootComponent(component)注册应用根组件见上文入口分析disableErrorHandling()禁用默认错误处理源自 packages/expo/src/errors/ExpoErrorManagerreloadAppAsync()编程式触发应用重载isRunningInExpoGo()/getExpoGoProjectConfig()判断当前是否运行在 Expo Go 中并读取其工程配置。其实现packages/expo/src/environment/ExpoGo.ts通过requireNativeModule(ExpoGo)探测原生模块是否存在——只有在 Expo Go 宿主中该模块才存在因此该方法不会在独立构建中抛错而是返回null。原生模块核心类与方法类EventEmitter、SharedObject、SharedRef、NativeModule、UnavailabilityError、CodedError方法requireNativeModule、requireOptionalNativeModule、requireNativeViewManager别名requireNativeView、registerWebModule工具Platform、uuid、createSnapshotFriendlyRef、useReleasingSharedObject系列 Hooks类型EventSubscription、TypedArray及各类子类型权限体系PermissionStatus、createPermissionHook与PermissionResponse等HooksuseEvent、useEventListener见 packages/expo/src/hooks/useEvent.ts。同时 packages/expo/package.json 的exports字段定义了若干子路径入口例如expo/dom、expo/fetch、expo/config、expo/internal/*等其中expo/fetch指向 Winter 运行时中的 fetch 实现。Winter把 Web 标准 API 补进原生运行时packages/expo/src/winter/目录packages/expo/src/winter/是 Expo 为原生环境补齐 Web 标准 API 的实现集合包含AbortSignal、DOMException、FormData、TextDecoder、TextDecoderStream、urlURL 解析以及完整的fetch/子目录。从源码结构看packages/expo/src/winter/index.ts 仅一行import ./runtime真正的初始化逻辑分布在runtime.ts、runtime.native.ts与installGlobal.ts中这套实现会在模块加载时把相关全局对象注入运行时从而让同一套 Web 语义代码在原生端与浏览器端行为一致。为什么选择 Expo四个核心理由README 将 Expo 的价值主张浓缩为四点这些主张在当前仓库中均有直接依据天生通用Universal by default一份代码库同时面向 Android、iOS 与 Web且额外支持 tvOS 与 Android TV。仓库中的apps目录正是多端共存的实证——例如apps/bare-expo、apps/native-component-list533 个.tsx组件示例与apps/test-suite78 个测试文件都同时服务于 Android/iOS/Web 三端。生产可用Production-readyExpo 被用于 App Store 与 Play Store 上数以万计的应用中其宿主应用 Expo Go 本身apps/expo-go/包含 498 个 Android 文件与 473 个 iOS 文件就是最大的自举验证。深度可定制Customizable all the way downConfig Plugins 与 Expo Modules API 让开发者可以在需要时直接触及原生层。开源Open source本仓库以 MIT 协议发布见根目录 LICENSE开发全程公开进行。参与贡献与许可证欢迎提交 bug 报告、修复与改进。expo包本地开发环境的搭建说明见 packages/expo/CONTRIBUTING.md仓库级通用贡献指南见根目录 CONTRIBUTING.md。Expo 源码在 MIT License 下发布。小结packages/expo中的expo包是整个 Expo 生态的运行时门面它通过Expo.fx.tsx完成启动副作用注入、通过registerRootComponent统一三端渲染入口、通过Expo.ts向开发者导出模块核心类、权限体系与原生模块加载方法并在 Winter 目录中补齐了原生端的 Web 标准 API。而在expo包之外Expo SDK 的各个模块、Expo Router、Expo Modules API、Expo UI、DOM 组件、CNG 与 EAS 共同构成了一个每一块都可独立使用的完整开发与发布体系。按照 README 的标准流程npx create-expo-applatest my-app cd my-app npx expo start你就能在数分钟内启动一个同时面向 Android、iOS 与 Web 的通用原生应用。【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考