ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

【Bug已解决】[Mobile] unimodule.json makes Expo exclude onnxruntime-react-native from autolinking - Nati…

【Bug已解决】[Mobile] unimodule.json makes Expo exclude onnxruntime-react-native from autolinking - Nati… 【Bug已解决】[Mobile] unimodule.json makes Expo exclude onnxruntime-react-native from autolinking - NativeModules.Onnxruntime is null 解决方案一、现象长什么样在 React Native Expo 项目里集成onnxruntime-react-nativeORT 的 RN 原生模块iOS/Android 上运行时直接崩或拿不到原生模块import { NativeModules } from react-native; console.log(NativeModules.Onnxruntime); // null // 后续 session.create 调用因 NativeModules 为 null 而崩溃最小信号原生模块没被链接 - NativeModules.Onnxruntime null Expo 自动链接autolinking名单里没有 onnxruntime-react-native 报错/崩溃在模块加载阶段不是推理阶段注意这是Expo 自动链接配置问题不是 ORT 推理 bug。Expo 的 autolinking 依据某些配置文件决定哪些原生模块参与链接onnxruntime-react-native被漏掉了。二、背景React Native 0.60 用autolinking自动链接你npm install一个带原生代码的库构建时 RN 的 autolinking 工具会扫描node_modules里各包的配置文件自动把它们的 iOS pod / Android gradle 依赖加进工程不用手动react-native link。Expo 在此基础上有一套自己的模块配置expo.modules、unimodule.json/expo-module.config等用来决定哪些库被 Expo 的预构建prebuild和原生宿主包含。问题就出在onnxruntime-react-native这个包没有被正确登记进 Expo 的 autolinking 配置于是iOS 上pod install时它的 pod 没被加进Podfile原生模块不编译进 appAndroid 上它的react-native-config/settings.gradle条目缺失不编进 apk运行时NativeModules.Onnxruntime自然是null因为原生端根本没这个模块。unimodule.json在这里是 Expo 旧版模块清单的格式新版用expo-module.config.js。如果这份清单里没有列onnxruntime-react-nativeExpo 的 autolinking 就会把它排除。三、根因根因是Expo 的 autolinking 配置unimodule.json/ 模块清单没有包含onnxruntime-react-native导致预构建/链接阶段把它排除原生模块不进 app运行时NativeModules.Onnxruntime为 null清单漏登记onnxruntime-react-native包本身可能没在expo-module.config.js里声明自己是 Expo 兼容模块或宿主项目的unimodule.json没列它autolinking 扫不到。autolinking 排除Expo prebuild 依据清单生成原生工程缺登记 - pod/gradle 不生成 - 原生模块缺席。运行时 nullJS 侧NativeModules.Onnxruntime依赖原生端导出该模块原生端没编进去自然null任何调用崩。不是 ORT 推理错模块根本没加载连 session 都建不了。所以这不是数值错而是Expo 原生模块链接配置缺口导致 ORT RN 模块没编进 app。四、最小可运行复现下面用 JS 伪代码模拟“autolinking 清单过滤掉未登记模块导致 NativeModules 为 null”// Expo autolinking 依据清单决定链接哪些模块 const EXPO_MODULE_MANIFEST { modules: [ expo-camera, expo-file-system, // onnxruntime-react-native 没在这里 - 被排除 ], }; // autolinking 生成原生依赖时只取清单内的 function autolink(packages) { return packages.filter((p) EXPO_MODULE_MANIFEST.modules.includes(p)); } const installed [onnxruntime-react-native, expo-camera]; const linked autolink(installed); console.log(被链接的模块:, linked); // 不含 onnxruntime-react-native // 运行时原生端没编入 - NativeModules 为 null const NativeModules {}; console.log(NativeModules.Onnxruntime:, NativeModules.Onnxruntime ?? null); // - null因为没被链接跑这个逻辑onnxruntime-react-native不在清单autolink过滤后不含它运行时NativeModules.Onnxruntime为null。这复现了“清单漏登记 - 模块不链接 - NativeModules 为 null”的机制。五、解决方案第一层最小直接修复最小修复把onnxruntime-react-native登记进 Expo 的 autolinking 配置让原生模块被链接进 app。几种做法// 1) 在 onnxruntime-react-native 包里确保 expo-module.config.js 声明兼容 // onnxruntime-react-native/expo-module.config.js: { platforms: [ios, android], ios: { modules: [Onnxruntime] } } // 2) 宿主项目显式包含expo 配置 // app.json / app.config.js: { expo: { plugins: [ // 某些包需要在这里声明插件以触发链接 ] } } // 3) 重新生成原生工程 // npx expo prebuild --clean // npx pod-install ios这一步让pod install/ gradle 把 ORT RN 原生模块编进 app运行时NativeModules.Onnxruntime不再是null。六、解决方案第二层结构性改进把“哪些 RN 原生模块必须被 Expo autolinking 包含”收口成唯一的配置对象OrtExpoAutolinkPolicy项目配置与 CI 读它from dataclasses import dataclass, field from typing import Tuple dataclass(frozenTrue) class OrtExpoAutolinkPolicy: onnxruntime-react-native 在 Expo autolinking 的单一事实来源。 # 必须被 autolinking 包含的 RN 原生模块 required_modules: Tuple[str, ...] (onnxruntime-react-native,) # 各平台必须链接 platforms: Tuple[str, ...] (ios, android) # 包内必须声明的 expo 模块配置 package_must_declare: Tuple[str, ...] (expo-module.config.js,) # prebuild 后必须验证原生模块存在 verify_after_prebuild: bool True def is_required(self, module: str) - bool: return module in self.required_modules def describe(self) - str: return onnxruntime-react-native 必须进 Expo autolinkingiOS/Android 都链接 POLICY OrtExpoAutolinkPolicy() def check_manifest(manifest_modules: list, policy: OrtExpoAutolinkPolicy POLICY) - list: missing [m for m in policy.required_modules if m not in manifest_modules] if missing and policy.verify_after_prebuild: raise RuntimeError(fExpo autolinking 缺失模块: {missing}) return missing所有 Expo 项目配置与 CI 读同一份POLICYORT RN 模块不会被漏链接。七、解决方案第三层断言 / CI 守护把“onnxruntime-react-native 被 Expo 链接、NativeModules 非空”做成断言。下面用 pytest 风格守护复用第四节逻辑import pytest def test_module_required(policy): assert onnxruntime-react-native in policy.required_modules assert policy.is_required(onnxruntime-react-native) is True def test_platforms_covered(policy): assert ios in policy.platforms assert android in policy.platforms def test_manifest_must_include(policy): with pytest.raises(RuntimeError): check_manifest([expo-camera]) # 缺 onnxruntime-react-native def test_complete_manifest_passes(policy): assert check_manifest([onnxruntime-react-native, expo-camera]) []这四组断言锁住(1) 模块必含(2) iOS/Android 都覆盖(3) 清单缺模块即失败(4) 齐备通过。CI 跑通即代表 autolinking 配置不被漏。八、排查清单遇到 Expo 上 NativeModules.Onnxruntime 为 null看 autolinking 清单unimodule.json/expo-module.config.js里有没有 onnxruntime-react-native。看 pod/ gradle 是否生成Podfile.lock/settings.gradle里有没有 ORT RN 原生依赖。查包是否声明 expo 兼容onnxruntime-react-native里有没有expo-module.config.js。临时修复把它加进清单 expo prebuild --cleanpod install。统一策略对象用OrtExpoAutolinkPolicy固化。CI 守护断言模块在清单、平台覆盖、缺即失败。不要手动 link 旧式用 autolinking 正确声明避免 RN 新版不认。九、小结[Mobile] unimodule.json makes Expo exclude onnxruntime-react-native from autolinking - NativeModules.Onnxruntime is null的根因是Expo 的 autolinking 配置unimodule.json/ 模块清单没有包含onnxruntime-react-native预构建/链接阶段把它排除原生模块不编进 iOS/Android app运行时NativeModules.Onnxruntime为null任何调用崩溃。最小修复是把该包登记进 Expo autolinking包内声明expo-module.config.js、宿主清单包含、expo prebuild --cleanpod install结构性改进是用唯一的OrtExpoAutolinkPolicy固化必含模块CI 用四组断言守护“模块必含、平台覆盖、缺即失败、齐备通过”。记住RN 原生模块要进 Expo 的 autolinking 清单才会被链接漏登记运行时就是 null。
返回列表