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",
  }
}
*/
相关推荐
寅时码4 小时前
React 之死·终章:一个 useRef,把闭包陷阱、依赖数组、漫天 rerender 全送走
前端·react.js·ai编程
不好听6134 小时前
HTML 事件监听机制:从 DOM Level 0 到 React 合成事件
前端·react.js·html
wordbaby4 小时前
为什么刷新页面就 404?聊聊 SPA 路由与 Nginx 的那点事
前端
不好听6134 小时前
React 核心概念:JSX、组件与数据驱动
前端·react.js
触底反弹4 小时前
🔥 React 零基础入门(中):500 行屎山代码到组件化的蜕变
前端·javascript·react.js
不好听6134 小时前
React vs Vue:两大前端框架技术选型深度对比
前端·vue.js·react.js
GuWenyue4 小时前
Cursor黑盒拆解!1套LangChain.js手写Mini编程Agent,自动生成React项目,效率提升60%
前端·数据库·人工智能
GuWenyue4 小时前
传统Agent工具两大痛点!300行代码落地MCP跨语言工具,彻底解耦LLM与工具
前端·人工智能·算法
小林ixn5 小时前
从 onclick 到 React 合成事件,再到完整应用逻辑:一次前端架构的深度剖析
前端·react.js·前端框架
同勉共进5 小时前
记一例 vibe coding + gcc bug 导致的线程池死锁问题
c++·线程池·gcc·死锁·vibe coding