React Native中bundleResourceIO导致Metro打包挂起问题求助
解决@tensorflow/tfjs-react-native的bundleResourceIO导致打包挂起问题
针对使用bundleResourceIO时React Native打包无响应的问题,可按以下步骤排查修复:
1. 修正模型文件的导入方式
当前导入方式错误,React Native无法正确解析直接import的JSON和二进制资源文件,需改为require加载:
// 替换原导入代码 const modelJSON = require('../models/cls/model.json'); const modelWeights = require('../models/cls/model.bin');
注意:model.json默认导出整个JSON对象,无需命名导入;model.bin作为二进制资源,通过require可被Metro正确识别为静态资源。
2. 完善Metro配置文件
需确保metro.config.js完整继承默认配置,同时添加二进制资源支持,建议修改为:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const customConfig = { resolver: { // 添加bin到资源扩展名列表 assetExts: [...getDefaultConfig(__dirname).resolver.assetExts, 'bin'], sourceExts: ['js', 'json', 'ts', 'tsx', 'jsx'], }, transformer: { getTransformOptions: async () => ({ transform: { experimentalImportSupport: false, inlineRequires: true, }, }), }, }; module.exports = mergeConfig(getDefaultConfig(__dirname), customConfig);
该配置可避免Metro在解析二进制权重文件时陷入死循环。
3. 清理Metro缓存
缓存异常可能导致打包挂起,执行以下命令重置缓存:
npx react-native start --reset-cache
之后重新运行npx react-native run-android。
4. 验证模型文件一致性
- 检查
model.json中的weightsManifest字段,确保其中的文件名与model.bin完全一致(Android对文件名大小写敏感)。 - 直接用本地JSON解析工具打开
model.json,确认文件格式未损坏。
5. 确保依赖版本匹配
检查package.json中@tensorflow/tfjs和@tensorflow/tfjs-react-native的版本是否一致,版本不兼容可能引发底层资源解析错误。
修正后的最小可复现代码
import React from 'react' import { StyleSheet, Text, View } from 'react-native' import * as tf from '@tensorflow/tfjs' import { bundleResourceIO } from '@tensorflow/tfjs-react-native' // 修正导入方式 const modelJSON = require('../models/cls/model.json'); const modelWeights = require('../models/cls/model.bin'); class App extends React.Component { state = { isTfReady: false, isModelReady: false } async componentDidMount() { await tf.ready() this.setState({ isTfReady: true }) try { this.model = await this.loadModel() this.setState({ isModelReady: true }) } catch (e) { console.error('模型加载失败:', e) } } async loadModel() { const bundled = bundleResourceIO(modelJSON, modelWeights) const model = await tf.loadGraphModel(bundled) console.log("Model loaded!"); return model; }; render() { return ( <View style={styles.container}> <Text>TFJS ready? {this.state.isTfReady ? 'Yes' : ''}</Text> <Text> Model ready?{' '} {this.state.isModelReady ? 'Yes' : 'Loading Model...'} </Text> </View> ) } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', } }) export default App
内容的提问来源于stack exchange,提问作者borschy
相关产品推荐
相关产品推荐

