You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Expo React Native组件打包为AAR及原生Android/iOS集成问题求助

Expo React Native组件打包为AAR及原生Android/iOS集成问题求助

我完全理解你现在的困扰——把Expo RN组件封装成可复用的原生库确实比普通RN项目复杂不少,尤其是处理依赖和打包AAR这块踩坑点特别多。我来给你一步步拆解可行的解决方案:

一、先搞定Expo项目的原生化预准备

因为Expo有自己的打包和依赖管理逻辑,不能直接用原生RN的react-native bundle命令,得先把项目转换成可原生编译的结构:

  • 运行npx expo prebuild生成原生Android和iOS目录,这一步会自动处理Expo依赖的原生配置
  • 确保你的HelloWorldWidget组件已经在RN端注册为可被原生调用的模块:
// 项目根目录index.js
import { AppRegistry } from 'react-native';
import HelloWorldWidget from './path/to/HelloWorldWidget';

// 注册组件,原生端会用这个名称调用
AppRegistry.registerComponent('HelloWorldWidget', () => HelloWorldWidget);

二、Android端:打包可复用AAR的正确姿势(解决依赖缺失)

1. 新建Android Library模块

不要直接修改默认的app模块,而是在Android项目里新建一个Android Library(比如命名为rn-widget-library)——这是打包AAR的基础,因为只有Library模块才能导出可复用的AAR。

2. 配置依赖与资源

  • 在Library模块的build.gradle里,声明所有需要的依赖(包括RN核心、hermes、react-native-svg等),并开启依赖传递,这样宿主app引入AAR时会自动拉取这些依赖:
// rn-widget-library/build.gradle
dependencies {
    // RN核心依赖,版本和你项目里的保持一致
    implementation "com.facebook.react:react-native:0.72.+"
    implementation "com.facebook.hermes:hermes-android:0.72.+"
    // 第三方库依赖,比如react-native-svg
    implementation project(':react-native-svg')
}

// 开启依赖传递,让宿主app自动获取所需依赖
configurations.all {
    transitive = true
}
  • 用Expo的命令生成正确的JS Bundle和资源,替代原生RN的bundle命令:
npx expo export -p android --bundle
  • 把生成的index.android.bundle放到Library模块的src/main/assets目录,把图片等资源复制到对应的res/drawableres/mipmap等目录。

3. 封装原生ViewWrapper

在Library模块里写一个原生View类,封装ReactRootView,让宿主app可以像用普通原生View一样引用你的RN组件:

// rn-widget-library/src/main/java/com/yourcompany/rnwidgetlibrary/RNWidgetView.java
package com.yourcompany.rnwidgetlibrary;

import android.app.Activity;
import android.content.Context;
import android.app.Application;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.horcrux.svg.SvgPackage; // react-native-svg的原生Package

public class RNWidgetView extends ReactRootView implements DefaultHardwareBackBtnHandler {
    private ReactInstanceManager mReactInstanceManager;

    public RNWidgetView(Context context) {
        super(context);
        // 初始化RN实例管理器
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication((Application) context.getApplicationContext())
                .setCurrentActivity((Activity) context)
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .addPackage(new SvgPackage()) // 注册第三方库的Package
                .setUseDeveloperSupport(false) // 生产环境关闭开发者支持
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        // 启动你的RN组件,这里的名称要和RN端注册的一致
        startReactApplication(mReactInstanceManager, "HelloWorldWidget", null);
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        // 处理返回键逻辑,按需实现
    }
}

4. 打包AAR

在Android Studio里,选中rn-widget-library模块,点击顶部菜单栏的Build > Make Module 'rn-widget-library',生成的AAR会在rn-widget-library/build/outputs/aar/目录下。

5. 宿主app集成

把AAR复制到宿主app的libs目录,然后在宿主app的build.gradle里添加引用:

// 宿主app build.gradle
dependencies {
    implementation files('libs/rn-widget-library-release.aar')
}

// 记得添加RN的maven仓库,不然依赖会拉取失败
repositories {
    mavenCentral()
    maven { url 'https://maven.google.com' }
    maven { url "$rootDir/../node_modules/react-native/android" }
    maven { url "$rootDir/../node_modules/jsc-android/dist" }
}

之后就可以在宿主app的布局里直接使用RNWidgetView了,或者在代码里动态初始化。

三、iOS端:打包成Framework的思路

iOS端的逻辑和Android类似:

  • npx expo prebuild -p ios生成原生iOS项目
  • 新建一个Cocoa Touch Framework模块,把Expo生成的JS Bundle和资源导入
  • 封装一个UIView子类,初始化RCTRootView并注册你的HelloWorldWidget组件
  • 用CocoaPods管理依赖,在Framework的podspec里声明RN核心、react-native-svg等依赖,确保宿主app集成时能自动获取

四、常见坑点排查

  • 依赖解析失败:检查Library模块的build.gradle是否开启了transitive = true,以及宿主app是否添加了RN的maven仓库
  • react-native-svg不生效:确保在原生端正确注册了SvgPackage(Android)或RCTSVGModule(iOS),并且打包时把第三方库的原生代码包含到了AAR/Framework里
  • Expo资源不显示:一定要用npx expo export命令生成资源,不要手动复制,因为Expo会对资源做特殊处理

内容来源于stack exchange

火山引擎 最新活动