React Native使用Protocol Buffer遇非法令牌错误‘Expected’求助
React Native中使用ProtobufJS加载GTFS .proto文件报错解决方案
问题背景
开发基于GTFS的路况提醒应用,代码在原生JS/TS环境正常运行,但在React Native(.js文件)中执行时出现错误提示:illegal token 'Expected'。已将GTFS的protocol.proto文件放置在android/app/src/main/assets目录,且通过RNFS验证可读取文件内容,使用protobufjs库处理Protocol Buffer。
原代码片段:
const url = CONSTANTS.API_URL; protobuf.load('protocol.proto', (err, root) => { if (err) { throw err; } const TransitRealtime = root.lookupType('transit_realtime.FeedMessage'); fetch(url) .then(response => response.arrayBuffer()) .then(buffer => { const message = TransitRealtime.decode(new Uint8Array(buffer)); const object = TransitRealtime.toObject(message, { longs: String, enums: String, bytes: String, }); console.log(object.entity[1].alert.headerText); console.log(object.entity[1].alert.descriptionText); }) .catch(error => { console.error('There was a problem with the fetch operation:', error); }); });
问题原因
protobuf.load方法依赖Node.js的fs模块读取本地文件,但React Native的Assets文件系统逻辑与Node.js不同,直接传入protocol.proto路径无法正确读取文件内容,导致protobufjs解析的内容无效,抛出语法错误。
解决方案
通过RNFS读取Assets中的.proto文件内容,再使用protobuf.parse方法解析内容生成ProtoRoot,替代protobuf.load。
修改后的代码:
import RNFS from 'react-native-fs'; import protobuf from 'protobufjs'; const url = CONSTANTS.API_URL; // Android下Assets文件的路径 const protoFilePath = `${RNFS.MainBundlePath}/protocol.proto`; RNFS.readFile(protoFilePath, 'utf8') .then(protoContent => { // 解析proto内容生成root const root = protobuf.parse(protoContent).root; const TransitRealtime = root.lookupType('transit_realtime.FeedMessage'); return fetch(url) .then(response => response.arrayBuffer()) .then(buffer => { const message = TransitRealtime.decode(new Uint8Array(buffer)); const object = TransitRealtime.toObject(message, { longs: String, enums: String, bytes: String, }); console.log(object.entity[1].alert.headerText); console.log(object.entity[1].alert.descriptionText); }); }) .catch(error => { console.error('Error:', error); });
额外注意事项
- 确保已安装
react-native-fs并完成原生端配置(Android需在android/app/build.gradle中添加相关配置,iOS可使用自动链接) - iOS环境下Assets文件路径与Android一致,直接使用
RNFS.MainBundlePath即可 - 若
.proto文件依赖其他proto文件,需将所有依赖文件放入Assets目录,并在解析时通过protobufjs的resolve选项处理导入逻辑
内容的提问来源于stack exchange,提问作者CuriousCoder
相关产品推荐
相关产品推荐

