乐闻世界logo
搜索文章和话题

什么是Expo Development Build?它与Eject有什么区别?

2月21日 14:12

在Expo开发过程中,开发者可能会遇到需要超出Expo SDK提供功能的场景。这时需要使用Expo Development Build或Eject流程来扩展应用能力。

Expo Development Build:

Development Build是推荐的扩展方式,它允许在保持Expo工作流的同时添加自定义原生代码。

特点:

  • 保留Expo的开发体验和OTA更新能力
  • 可以添加自定义原生模块
  • 支持所有Expo SDK功能
  • 更容易维护和升级

创建Development Build:

bash
# 安装EAS CLI npm install -g eas-cli # 配置EAS eas build:configure # 创建开发构建 eas build --profile development --platform android

配置文件:

eas.json中配置development profile:

json
{ "build": { "development": { "developmentClient": true, "distribution": "internal" } } }

添加自定义原生模块:

  1. 创建原生模块目录:
shell
my-app/ ├── android/ │ └── src/ │ └── main/ │ └── java/ │ └── com/ │ └── myapp/ │ └── CustomModule.java ├── ios/ │ └── myapp/ │ └── CustomModule.m
  1. Android模块示例:
java
package com.myapp; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.Promise; public class CustomModule extends ReactContextBaseJavaModule { public CustomModule(ReactApplicationContext context) { super(context); } @Override public String getName() { return "CustomModule"; } @ReactMethod public void customMethod(Promise promise) { try { // 自定义原生逻辑 promise.resolve("Success"); } catch (Exception e) { promise.reject("Error", e.getMessage()); } } }
  1. iOS模块示例:
objc
#import <React/RCTBridgeModule.h> @interface RCT_EXTERN_MODULE(CustomModule, NSObject) RCT_EXTERN_METHOD(customMethod:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) @end
  1. JavaScript中使用:
typescript
import { NativeModules } from 'react-native'; const { CustomModule } = NativeModules; CustomModule.customMethod() .then(result => console.log(result)) .catch(error => console.error(error));

Eject流程:

Eject会将Expo项目转换为纯React Native项目,完全脱离Expo生态系统。

特点:

  • 完全控制原生代码
  • 无法使用Expo Go
  • 失去OTA更新能力
  • 需要自己管理原生依赖

Eject步骤:

bash
# Eject项目 npx expo eject # 选择模板 # - Bare: 纯React Native项目 # - ExpoKit: 保留部分Expo功能(已弃用)

何时使用Development Build:

  • 需要添加自定义原生模块
  • 需要使用第三方原生库
  • 需要访问特定的原生API
  • 希望保持Expo的开发体验

何时使用Eject:

  • 需要完全控制原生代码
  • 项目不再需要Expo的任何功能
  • 需要深度定制原生层
  • 团队有丰富的原生开发经验

最佳实践:

  1. 优先使用Development Build:除非有特殊需求,否则不要Eject

  2. 模块化原生代码:将原生代码组织成独立的模块,便于维护

  3. 版本控制:将原生代码纳入Git版本控制

  4. 文档记录:详细记录自定义模块的使用方法和API

  5. 测试覆盖:为原生模块编写单元测试和集成测试

  6. 性能监控:监控原生模块的性能影响

常见问题:

  1. 模块注册:确保原生模块正确注册到React Native桥接

  2. 权限配置:在app.json中添加必要的权限声明

  3. 依赖冲突:注意原生依赖之间的版本兼容性

  4. 平台差异:处理Android和iOS之间的API差异

  5. 调试困难:使用Flipper等工具调试原生代码

回退到Expo:

如果Development Build或Eject后出现问题,可以创建新的Expo项目并迁移JavaScript代码。

选择Development Build还是Eject取决于项目需求和团队技术栈,大多数情况下Development Build是更好的选择。

标签:Expo