Skip to content

快速开始 ​

安装 ​

bash
npm install -g proto-codegen
# 或
pnpm add -g proto-codegen

创建配置文件 ​

在项目根目录创建 proto-codegen.config.json:

json
{
  "input": {
    "protoDir": "./proto",
    "include": ["*.proto"],
    "exclude": ["*_test.proto"]
  },
  "output": {
    "dir": "./generated",
    "clientsDir": "clients",
    "typesDir": "types"
  },
  "generation": {
    "generateTypes": true,
    "generateClients": true
  }
}

准备 proto 文件 ​

把 .proto 文件放进 ./proto 目录。工具解析 google.api.http 注解来生成 HTTP 客户端:

protobuf
syntax = "proto3";

package example;

message GetUserRequest {
  string user_id = 1;
}

message GetUserResponse {
  string id = 1;
  string name = 2;
  string email = 3;
}

service UserService {
  rpc GetUser(GetUserRequest) returns (GetUserResponse) {
    option (google.api.http) = {
      get: "/api/v1/users/{user_id}"
    };
  }
}

生成代码 ​

bash
proto-codegen generate

生成的目录结构如下:

generated/
├── index.ts
├── clients/
│   ├── index.ts
│   ├── http-client.ts
│   └── user-client.ts
└── types/
    ├── index.ts
    └── example.ts

在前端里用起来 ​

生成器还会输出一个 HttpClient 接口(在 generated/clients/http-client.ts),用项目里现成的 HTTP 库(fetch、axios 等)实现它一次,所有生成的客户端就能用了:

typescript
import { HttpClient } from './generated/clients/http-client';

// 用你的 HTTP 库实现这个生成的接口——只需一次
class MyHttpClient implements HttpClient {
  async get<T>(url: string, params?: any): Promise<T> {
    const res = await fetch(url + '?' + new URLSearchParams(params));
    return res.json();
  }
  // post、put、delete、patch...
}

然后创建客户端调用——参数和返回值的类型都从 proto 自动推断:

typescript
import { UserServiceClient } from './generated/clients/user-client';

const userService = new UserServiceClient(new MyHttpClient());
const user = await userService.getUser({ userId: '123' }); // 类型是 GetUserResponse
console.log(user.id, user.name, user.email);

需要解包 { code, data, message } 之类的响应包装,或加路径前缀?见使用生成代码。

环境要求 ​

类型生成依赖 protoc 和 ts-proto,两者都要在 PATH 里:

  • protoc(Protocol Buffers 编译器)
  • ts-proto 随依赖安装,但要保证 protoc-gen-ts_proto 可执行文件能被找到

客户端层不依赖这两者,Node 18+ 即可运行。

下一步 ​