protoc-gen-ts_proto
protoc-gen-ts_proto 是从 Protocol Buffers 定义文件生成 TypeScript 类型定义的工具,适用于后端使用 gRPC 提供服务的场景。
工具说明
核心特性
- 文件映射:每个
.proto文件对应生成一个 TypeScript 文件 - 类型精确:支持完整的 Protocol Buffers 特性
- 性能优化:生成的代码经过性能优化
- 依赖处理:通过
import自动处理文件间的依赖关系
适用场景
- 后端使用 gRPC 提供服务
- 需要精确的类型定义
- 希望按模块清晰组织代码(每个 proto 文件一个 TypeScript 文件)
安装
安装 protoc
# macOS
brew install protobuf
# Linux
apt-get install protobuf-compiler
# 或从源码编译
# https://github.com/protocolbuffers/protobuf/releases
安装 protoc-gen-ts_proto
ts-proto 是一个 npm 包,有多种安装方式:
方式1:在后端项目中安装(如果后端项目没有 package.json,需要先初始化)
# 如果后端项目是纯 Go 项目,没有 package.json,需要先初始化
npm init -y
# 然后安装 ts-proto
npm install -D ts-proto
安装后,protoc-gen-ts_proto 插件位于 ./node_modules/.bin/protoc-gen-ts_proto
方式2:全局安装(推荐,避免在后端项目中添加 npm 依赖)
npm install -g ts-proto
# 安装后,插件路径通常是:
# macOS/Linux: /usr/local/bin/protoc-gen-ts_proto 或 ~/.npm-global/bin/protoc-gen-ts_proto
# 可以通过 which protoc-gen-ts_proto 查看实际路径
方式3:使用 Docker(推荐,完全避免本地环境依赖)
无需安装,直接使用 Docker 运行,见下面的 Docker 方式示例。
提示
对于纯后端项目,推荐使用方式2(全局安装)或方式3(Docker),避免在后端项目中添加 npm 依赖和 package.json 文件。
使用方式
后端 Makefile 配置
方式1:使用本地 node_modules(需要先 npm install)
FRONT_TYPES_DIR ?= ./frontend-types
PROTO_DIR := handler/grpc/proto
PROTO_FILES := $(shell find $(PROTO_DIR) -name "*.proto")
generate-front-types: ## 生成前端TypeScript类型定义
@echo "generating frontend types to $(FRONT_TYPES_DIR)..."
@mkdir -p $(FRONT_TYPES_DIR)
protoc --plugin=protoc-gen-ts_proto=./node_modules/.bin/protoc-gen-ts_proto \
--proto_path=$(PROTO_DIR) \
--ts_proto_out=$(FRONT_TYPES_DIR) \
--ts_proto_opt=exportCommonSymbols=false,outputClientImpl=false,esModuleInterop=true,onlyTypes=true \
$(PROTO_FILES)
@echo "Frontend types generated to $(FRONT_TYPES_DIR)"
方式2:使用全局安装的插件(推荐)
FRONT_TYPES_DIR ?= ./frontend-types
PROTO_DIR := handler/grpc/proto
PROTO_FILES := $(shell find $(PROTO_DIR) -name "*.proto")
PROTOC_GEN_TS_PROTO := $(shell which protoc-gen-ts_proto)
generate-front-types: ## 生成前端TypeScript类型定义
@mkdir -p $(FRONT_TYPES_DIR)
protoc --plugin=protoc-gen-ts_proto=$(PROTOC_GEN_TS_PROTO) \
--proto_path=$(PROTO_DIR) \
--ts_proto_out=$(FRONT_TYPES_DIR) \
--ts_proto_opt=exportCommonSymbols=false,outputClientImpl=false,esModuleInterop=true,onlyTypes=true \
$(PROTO_FILES)
说明:
PROTOC_GEN_TS_PROTO := $(shell which protoc-gen-ts_proto):动态查找全局安装的插件路径--ts_proto_opt=exportCommonSymbols=false,outputClientImpl=false,esModuleInterop=true,onlyTypes=true:只生成类型定义,不生成序列化方法和公共符号
命令行参数说明
--plugin=protoc-gen-ts_proto=路径:指定 TypeScript 生成器插件路径- 本地安装:
./node_modules/.bin/protoc-gen-ts_proto - 全局安装:使用
$(shell which protoc-gen-ts_proto)动态查找
- 本地安装:
--proto_path:指定 proto 文件的搜索路径,可以多次指定--ts_proto_out:指定 TypeScript 文件输出目录--ts_proto_opt:生成选项,多个选项用逗号分隔
方式3:使用 Docker(推荐,完全避免本地环境依赖)
FRONT_TYPES_DIR ?= ./frontend-types
generate-front-types: ## 生成前端TypeScript类型定义
@echo "generating frontend types to $(FRONT_TYPES_DIR)..."
@mkdir -p $(FRONT_TYPES_DIR)
docker run --rm \
-v $(PWD)/api:/api:ro \
-v $(PWD)/third_party:/third_party:ro \
-v $(PWD)/$(FRONT_TYPES_DIR):/output \
node:18-alpine sh -c "\
apk add --no-cache protobuf && \
npm install -g ts-proto && \
PROTOC_GEN_TS_PROTO=\$$(which protoc-gen-ts_proto) && \
protoc --plugin=protoc-gen-ts_proto=\$$PROTOC_GEN_TS_PROTO \
--proto_path=/api \
--proto_path=/third_party \
--ts_proto_out=/output \
--ts_proto_opt=exportCommonSymbols=false,outputClientImpl=false,esModuleInterop=true,onlyTypes=true \
/api/**/*.proto"
@echo "Frontend types generated to $(FRONT_TYPES_DIR)"