web通过离线编译protobuf,在线解析proto二进制数据

一、安装依赖

环境版本

bash 复制代码
$ node -v
v18.12.0

$ npm -v
8.19.2

为了使用ts类型推断,我这里安装ts-proto库,我用的版本是^2.7.0

bash 复制代码
$ npm i ts-proto

安装protoc工具

  • 这个是非web或node程序,一个可执行的.exe文件用来编译.proto文件;
  • 点击下方链接,选择你所属电脑的系统对应的工具,我这里是windows32位操作系统。

github.com/protocolbuf...

  • 下载完成后,解压缩到某个文件夹下,配置系统环境变量路径:
  • 查看protoc版本
cmd 复制代码
$ protoc --version
  • 这里是一个坑点,protoc默认从nodejs的根目录的node_modules文件夹去查找对应执行文件了,具体原因还不了解,可能是因为之前安装了npm i protoc -g导致的,这里我们规避一下,改一种写法:
cmd 复制代码
$ protoc.exe --version
libprotoc 30.2
  • 运行正常,安装步骤完结。

二、编译.proto文件

准备2个.proto 文件,a.protob.proto,其中a.proto使用import关键字引入了b.proto文件的类型

  • 当前你的工程目录为这样:
bash 复制代码
ts-proto-demo/
├── protos/
│   ├── a.proto
│   └── b.proto
├── package.json
├── tsconfig.json
└── README.md
protobuf 复制代码
// a.proto
syntax = "proto3";

package demo;

// 引入b.proto
import "b.proto";

message Post2 {
  string id2 = 1;
  string title2 = 2;
}
message Post {
  string id = 1;
  string title = 2;
  // b的User类型
  User author = 3;
  Post2 post2 = 4;
}
protobuf 复制代码
// b.proto
syntax = "proto3";

package demo;

message User {
  string id = 1;
  string name = 2;
}

开始编译

  • 执行protoc可执行文件
cmd 复制代码
protoc.exe \
--plugin=protoc-gen-ts_proto=".\\node_modules\\.bin\\protoc-gen-ts_proto.cmd" \
--proto_path=./protos/ \
--ts_proto_out=. \
./protos/a.proto

--plugin=protoc-gen-ts_proto=".\\node_modules\\.bin\\protoc-gen-ts_proto.cmd"

  • npm安装ts-proto库时,会在node_modules/.bin/文件夹下添加一个名为protoc-gen-ts_proto.cmd的可执行文件;
  • 注意!!!我是windows系统,所以选用.cmd结尾的文件;
  • 注意!!!我使用的是cmd运行脚本,所以--plugin路径使用".\\node_modules\\.bin\\protoc-gen-ts_proto.cmd"写法。
  • --proto_path=./protos/ 如果你有多个.proto文件需要编译,或者有互相引用的.proto文件,需要设置--proto_path,大致意思是包含proto_path文件夹下的所有.proto文件

  • --ts_proto_out=. 输出*.ts解析脚本目录,没什么好说的

  • ./protos/a.proto 需要编译的.proto文件

执行完成

三、查看结果

  • 当前你的工程目录为这样:
bash 复制代码
ts-proto-demo/
├── protos/
│   ├── a.proto
│   └── b.proto
├── a.ts
├── b.ts
├── package.json
├── tsconfig.json
└── README.md

a.ts文件内容:

正常我们只需要关心最终输出的类型,应该是Post类型,Post包含了Post2User类型。

四、使用

typescript 复制代码
import {Post} from "./a.ts"
const data: Uint8Array = // ***;
const result = Post.encode(data);
cosole.log(result);

// 你会得到类似下面的结果
/**
{
  id: '1',
  title: "标题1",
  author: {
   id: "3";
   name: "leo";
  },
  post2: {
      id2: '2',
      title2: "标题2",
  }
}
*/
相关推荐
@大迁世界1 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路10 分钟前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug14 分钟前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu1213815 分钟前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中37 分钟前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路41 分钟前
GDAL 实现矢量合并
前端
hxjhnct43 分钟前
React useContext的缺陷
前端·react.js·前端框架
前端 贾公子1 小时前
从入门到实践:前端 Monorepo 工程化实战(4)
前端
菩提小狗1 小时前
Sqlmap双击运行脚本,双击直接打开。
前端·笔记·安全·web安全
码农小韩1 小时前
基于Linux的C++学习——动态数组容器vector
linux·c语言·开发语言·数据结构·c++·单片机·学习