# @apollo/protobufjs 中文文档

规范地址：https://npmcn.com/package/%40apollo/protobufjs/

版本：1\.2\.8
npm 元数据更新时间：2026-04-30T19:42:18.351Z
中文译文更新时间：2026-11-06T10:53:28.649Z
软件包许可：BSD-3-Clause

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40apollo/protobufjs
原文对照：https://npmcn.com/package/%40apollo/protobufjs/?lang=original
项目主页：https://github.com/apollographql/protobuf.js
源码仓库：https://github.com/apollographql/protobuf.js

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：2.8 MB，113 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- 运行依赖：12 个
- 首次发布：2019-11-19T22:51:31.542Z
- 最新版本发布：2026-04-30T19:42:18.076Z
- 近 30 天下载量：18006593（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：17（近 12 个月 1 个）

## 中文简介

JavaScript( & TypeScript) 协议缓冲器 .

## 安装

```sh
npm install @apollo/protobufjs
```

也可以使用：`pnpm add @apollo/protobufjs`、`yarn add @apollo/protobufjs`、`bun add @apollo/protobufjs`

## README

# 阿波罗叉

我们准备了 [源重播](https://github.com/dcodeIO/protobuf.js) 因为我们需要修改包 用于阿波罗服务器.

**这个包只供阿波罗·塞弗使用.** 您不应该直接在其它上下文中使用它 。 它只应用于阿波罗服务器上的具体原生生物定义,当然不应用于用户控制的原生生物定义(阿波罗没有试图将所有仅会影响使用由用户控制的原生生物定义的上游弱点补上. )

1.0.0版本从 `master` 包含6.8.8版 加上一些未释放的犯法行为. [萨](https://github.com/protobufjs/protobuf.js/commit/4d490eb1bf71f5c5c4c9d253a2ffd36edea12386)

# 

![protobuf.js](https://github.com/dcodeIO/protobuf.js/raw/master/pbjs.png)

[![](https://img.shields.io/npm/v/protobufjs.svg)](https://npmjs.org/package/protobufjs) [![](https://travis-ci.org/dcodeIO/protobuf.js.svg?branch=master)](https://travis-ci.org/dcodeIO/protobuf.js) [![](https://img.shields.io/npm/dm/protobufjs.svg)](https://npmjs.org/package/protobufjs) [![donate ❤](https://img.shields.io/badge/donate-%E2%9D%A4-ff2244.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=dcode%40dcode.io&item_name=Open%20Source%20Software%20Donation&item_number=dcodeIO%2Fprotobuf.js)

**协议缓冲** 是一种语言中和,平台中和,可扩展的串行式结构数据,用于通信协议,数据存储,以及更多,最初由Google设计([见](https://developers.google.com/protocol-buffers/)) (中文(简体) ).

**(原始内容存档于2012-10-12). protobuf.js** 是 JavaScript 纯执行 [类型脚本](https://www.typescriptlang.org/) 支持 [节点.js](https://nodejs.org/) 和浏览器。 它很容易使用, 猛烈地快速 和工作出盒 [. proto (中文(简体) )](https://developers.google.com/protocol-buffers/docs/proto) 档案!

## 目录

-   [安装](https://npmcn.com/package/%40apollo/protobufjs/#readme-installation)  
    如何将protobuf.js纳入你的计划.
    
-   [使用量](https://npmcn.com/package/%40apollo/protobufjs/#readme-usage)  
    工具集使用简介.
    
    -   [有效信件](https://npmcn.com/package/%40apollo/protobufjs/#readme-valid-message)
    -   [工具集](https://npmcn.com/package/%40apollo/protobufjs/#readme-toolset)  
        
-   [实例](https://npmcn.com/package/%40apollo/protobufjs/#readme-examples)  
    几个例子让你开始.
    
    -   [使用. proto 文件](https://npmcn.com/package/%40apollo/protobufjs/#readme-using-proto-files)
    -   [使用 JSON 描述符](https://npmcn.com/package/%40apollo/protobufjs/#readme-using-json-descriptors)
    -   [仅使用反射](https://npmcn.com/package/%40apollo/protobufjs/#readme-using-reflection-only)
    -   [使用自定义类](https://npmcn.com/package/%40apollo/protobufjs/#readme-using-custom-classes)
    -   [使用服务](https://npmcn.com/package/%40apollo/protobufjs/#readme-using-services)
    -   [使用类型脚本](https://npmcn.com/package/%40apollo/protobufjs/#readme-usage-with-typescript)  
        
-   [命令行](https://npmcn.com/package/%40apollo/protobufjs/#readme-command-line)  
    如何使用命令行工具 .
    
    -   [用于 Java 脚本的 pbjs](https://npmcn.com/package/%40apollo/protobufjs/#readme-pbjs-for-javascript)
    -   [类型脚本的 pbts](https://npmcn.com/package/%40apollo/protobufjs/#readme-pbts-for-typescript)
    -   [反射对静态代码](https://npmcn.com/package/%40apollo/protobufjs/#readme-reflection-vs-static-code)
    -   [命令行 API](https://npmcn.com/package/%40apollo/protobufjs/#readme-command-line-api)  
        
-   [其他文件](https://npmcn.com/package/%40apollo/protobufjs/#readme-additional-documentation)  
    现有文献资源清单.
    
-   [业绩](https://npmcn.com/package/%40apollo/protobufjs/#readme-performance)  
    一些内部和业绩基准.
    
-   [兼容性](https://npmcn.com/package/%40apollo/protobufjs/#readme-compatibility)  
    关于浏览器和可选库兼容性的说明 .
    
-   [大楼](https://npmcn.com/package/%40apollo/protobufjs/#readme-building)  
    如何自己建造图书馆及其组件.
    

## 安装

### 节点.js

```
$> npm install @apollo/protobufjs [--save --save-prefix=~]
```

```js
var protobuf = require("@apollo/protobufjs");
```

**说明** 由于历史原因,这个图书馆的版本方案是无法兼容的。 对于保证的后向兼容性,总是依赖于 `~6.A.B` 改为 `^6.A.B` (因此 `--save-prefix` (见上文).

### 浏览器

发展:

```
<script src="//cdn.rawgit.com/dcodeIO/protobuf.js/6.X.X/dist/protobuf.js"></script>
```

生产:

```
<script src="//cdn.rawgit.com/dcodeIO/protobuf.js/6.X.X/dist/protobuf.min.js"></script>
```

**记住** 将版本标记替换为精确 [释放](https://github.com/dcodeIO/protobuf.js/tags) 您的项目取决于.

库支持CommonJS和AMD加载器,并在全球范围内输出为 `protobuf`。 。 。 .

### 分发量

如果捆绑大小是一个因素,则会有额外的剥离版本 [完整库](https://github.com/dcodeIO/protobuf.js/tree/master/dist) 排除某些功能的可用(~19kb gziped):

-   在与 JSON 描述器合作时(即由 [密码](https://npmcn.com/package/%40apollo/protobufjs/#readme-pbjs-for-javascript))和/或只进行反思,见 [轻型库](https://github.com/dcodeIO/protobuf.js/tree/master/dist/light) (~16kb gzipped),不包括解析器. 常见JS切入点为:
    
    ```js
    var protobuf = require("@apollo/protobufjs/light");
    ```
    
-   仅使用静态生成的代码工作时,请参见 [最小图书馆](https://github.com/dcodeIO/protobuf.js/tree/master/dist/minimal) (~ 6.5kb gzipped),也排除了反射. 常见JS切入点为:
    
    ```js
    var protobuf = require("@apollo/protobufjs/minimal");
    ```
    

## 使用量

由于JavaScript是一种动态打字语言,protobuf.js引入了a的概念 **有效消息** 为了尽可能提供最好的 [业绩](https://npmcn.com/package/%40apollo/protobufjs/#readme-performance) (作为副产品,适当的打字):

### 有效消息

> 有效消息是指(1)不遗漏任何所需的字段和(2)完全由线条格式作者理解的JS类型所组成的对象.

有效的电文有两种可能类型,编码器为了方便,可以和这两种信息一起工作:

-   **信件实例** (电文类在其原型上带有默认值的明显实例)总是(必须)通过设计满足有效电文的要求,并且
-   **普通 Java 脚本对象** 也满足了有效信息的要求.

简言之,有线格式写作机理解以下类型: 1

| 字段类型 | 预期联合来文类型(创建、编码) | 转换(从对象) |
| --- | --- | --- |
| s-/u-/int32 (韩语)  
s-/固定32个 | `number` (32位整数) | `value | 0` 如果签名  
`value >>> 0` 未签名的 |
| s-/u-/int 64 (韩语)  
s-/固定64个 | `Long`\- 喜欢(最佳)  
`number` (53位整数) | `Long.fromValue(value)` 与长.js  
`parseInt(value, 10)` 否则 |
| 浮动  
双 | `number` | `Number(value)` |
| 嘘 | `boolean` | `Boolean(value)` |
| 字符串 | `string` | `String(value)` |
| 字节 | `Uint8Array` (优化)  
`Buffer` (节点下最佳)  
`Array.<number>` (8个位整数) | `base64.decode(value)` 如果一个 `string`  
`Object` 无零 `.length` 假设为缓冲 |
| 语句 | `number` (32位整数) | 查找数字代号,如果 `string` |
| 消息 | 有效消息 | `Message.fromObject(value)` |

-   明确 `undefined` 财务报告和审定财务报表 `null` 如果字段是可选的,则视为未设置.
-   重复字段为 `Array.<T>`。 。 。 .
-   地图字段是 `Object.<string,T>` 键为相应值的字符串表示式或8个字符长 二进制散列字符串 `Long`\-喜欢.
-   类型标记为 _最佳_ 提供最佳性能,因为不需要转换步骤(即数字到低位和高位或基数64字符串来缓冲).

### 工具集

考虑到这一点,并且出于性能原因,每个信息类都提供了一套截然不同的方法,每种方法只做一件事. 这避免了不必要的断言/冗余操作,因为性能令人关切,但也迫使用户进行校验(普通JavaScript对象) _可能会_ 必要时,例如,在处理用户输入时,就明确发出有效的信息.

**说明** 那个 `Message` 下文指任何信件类.

-   **信件. 确认**(新闻: `Object`: `null|string`  
    核实 **普通 Java 脚本对象** 满足有效电文的要求,因此可以不发问题地编码. 它不扔而是将错误消息作为字符串返回,如果有的话.
    
    ```js
    var payload = "invalid (not an object)";
    var err = AwesomeMessage.verify(payload);
    if (err)
      throw Error(err);
    ```
    
-   **Message.encode 消息编码**(新闻: `Message|Object` \[,作家: `Writer`\[ \]: `Writer`  
    编码 a **消息实例** 无效 **普通 Java 脚本对象**。这种方法并不隐含地验证消息,由用户确保有效有效消息.
    
    ```js
    var buffer = AwesomeMessage.encode(message).finish();
    ```
    
-   **消息. encode 有限**(新闻: `Message|Object` \[,作家: `Writer`\[ \]: `Writer`  
    喜欢 `Message.encode` 但也预留了信息长度作为瓦林.
    
-   **信件. 解码**(阅读: `Reader|Uint8Array`: `Message`  
    将缓冲解码为 a **消息实例**如果缺少所需的字段,则丢出一个 `util.ProtocolError` 带有 `instance` 属性设置到迄今为止已解码的信件。 如果线条格式无效, 它会扔出一个 `Error`。 。 。 .
    
    ```js
    try {
      var decodedMessage = AwesomeMessage.decode(buffer);
    } catch (e) {
        if (e instanceof protobuf.util.ProtocolError) {
          // e.instance holds the so far decoded message with missing required fields
        } else {
          // wire format is invalid
        }
    }
    ```
    
-   **信件. 解码限制**(阅读: `Reader|Uint8Array`: `Message`  
    喜欢 `Message.decode` 但另外读取了预想中的信息的长度为一瓦林.
    
-   **信件. 创建**(财产: `Object`: `Message`  
    创建新 **消息实例** 从符合有效消息要求的一组属性。 在适当情况下,建议采用 `Message.create` 结束 `Message.fromObject` 因为它不可能进行多余的转换.
    
    ```js
    var message = AwesomeMessage.create({ awesomeField: "AwesomeString" });
    ```
    
-   **信件。 来自对象**(目标: `Object`: `Message`  
    转换任何非验证 **普通 Java 脚本对象** 改为 **消息实例** 采用上表概述的转换步骤.
    
    ```js
    var message = AwesomeMessage.fromObject({ awesomeField: 42 });
    // converts awesomeField to a string
    ```
    
-   **信件。 到对象**(新闻: `Message` \[,选项: `ConversionOptions`\[ \]: `Object`  
    转换 a **消息实例** 对任意行为 **普通 Java 脚本对象** 用于与其他图书馆或存储的互操作性。 生成的平版 JavaScript 对象 _可能会_ 仍然满足有效消息的要求,取决于指定的实际转换选项,但大部分时间不满足.
    
    ```js
    var object = AwesomeMessage.toObject(message, {
      enums: String,  // enums as string names
      longs: String,  // longs as strings (requires long.js)
      bytes: String,  // bytes as base64 encoded strings
      defaults: true, // includes default values
      arrays: true,   // populates empty arrays (repeated fields) even if defaults=false
      objects: true,  // populates empty objects (map fields) even if defaults=false
      oneofs: true    // includes virtual oneof fields set to the present field's name
    });
    ```
    

为参考,下图旨在显示不同方法与有效消息概念之间的关系:

![Toolset Diagram](https://protobufjs.github.io/protobuf.js/toolset.svg)

> 换句话说: `verify` 说明电话 `create` 或者说 `encode` 直接在平面对象上将\[分别产生有效消息\]成功. `fromObject`另一方面,从更广泛的平面对象转换为创建有效消息。 ()[参考](https://github.com/dcodeIO/protobuf.js/issues/748#issuecomment-291925749)(中文(简体) )

## 实例

### 使用. proto 文件

可以使用完整的库来装入已存在的.proto文件,该库对定义进行剖析并编译,以便随时使用(基于反应的)消息类:

```protobuf
// awesome.proto
package awesomepackage;
syntax = "proto3";

message AwesomeMessage {
    string awesome_field = 1; // becomes awesomeField
}
```

```js
protobuf.load("awesome.proto", function(err, root) {
    if (err)
        throw err;

    // Obtain a message type
    var AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage");

    // Exemplary payload
    var payload = { awesomeField: "AwesomeString" };

    // Verify the payload if necessary (i.e. when possibly incomplete or invalid)
    var errMsg = AwesomeMessage.verify(payload);
    if (errMsg)
        throw Error(errMsg);

    // Create a new message
    var message = AwesomeMessage.create(payload); // or use .fromObject if conversion is necessary

    // Encode a message to an Uint8Array (browser) or Buffer (node)
    var buffer = AwesomeMessage.encode(message).finish();
    // ... do something with buffer

    // Decode an Uint8Array (browser) or Buffer (node) to a message
    var message = AwesomeMessage.decode(buffer);
    // ... do something with message

    // If the application uses length-delimited buffers, there is also encodeDelimited and decodeDelimited.

    // Maybe convert the message back to a plain object
    var object = AwesomeMessage.toObject(message, {
        longs: String,
        enums: String,
        bytes: String,
        // see ConversionOptions
    });
});
```

此外,如果首选的话,可以通过省略回调来使用承诺语法:

```js
protobuf.load("awesome.proto")
    .then(function(root) {
       ...
    });
```

### 使用 JSON 描述符

图书馆使用相当于.proto定义的JSON描述. 例如,以下定义与上文所见.proto定义相同:

```json
// awesome.json
{
  "nested": {
    "AwesomeMessage": {
      "fields": {
        "awesomeField": {
          "type": "string",
          "id": 1
        }
      }
    }
  }
}
```

JSON描述符与内部反射结构非常相似:

| 类型( T) | 扩展 | 类型属性 |
| --- | --- | --- |
| _反射对象_ |  | 选项 |
| _命名空间_ | _反射对象_ | 筑巢 |
| 根号 | _命名空间_ | **筑巢** |
| 类型 | _命名空间_ | **字段** |
| 数字 | _反射对象_ | **数值** |
| 外地 | _反射对象_ | 规则, **类型**, (中文(简体) ), **编号** |
| 地图字段 | 外地 | **密钥类型** |
| 1个 | _反射对象_ | **其中一个** (字段名称阵列) |
| 服务 | _命名空间_ | **方法** |
| 方法 | _反射对象_ | 类型, **请求类型**, (中文(简体) ), **响应类型**,请求Stream,响应Stream |

-   **粗体属性** 需要这样做. _斜体类型_ 是抽象的.
-   `T.fromJSON(name, json)` 从 JSON 描述符创建相应的反射对象
-   `T#toJSON()` 从相应的反射对象创建 JSON 描述符( 它的名称被用作母体内部的密钥)

完全使用 JSON 描述符而不是 . proto 文件可以只使用光库(在这种情况下不需要解析符) .

JSON 描述器可以用通常的方式装入:

```js
protobuf.load("awesome.json", function(err, root) {
    if (err) throw err;

    // Continue at "Obtain a message type" above
});
```

或者可以装入内线 :

```js
var jsonDescriptor = require("./awesome.json"); // exemplary for node

var root = protobuf.Root.fromJSON(jsonDescriptor);

// Continue at "Obtain a message type" above
```

### 仅使用反射

完整和光线库都包含全反射支持. 例如,人们可以仅仅通过思考来界定上述例子中所包含的.原始定义:

```js
...
var Root  = protobuf.Root,
    Type  = protobuf.Type,
    Field = protobuf.Field;

var AwesomeMessage = new Type("AwesomeMessage").add(new Field("awesomeField", 1, "string"));

var root = new Root().define("awesomepackage").add(AwesomeMessage);

// Continue at "Create a new message" above
...
```

关于反射结构的详细资料,可在 [API 文档](https://npmcn.com/package/%40apollo/protobufjs/#readme-additional-documentation)。 。 。 .

### 使用自定义类

消息类也可以以自定义功能来扩展,并且还可以注册带有被反射消息类型的自定义构建器:

```js
...

// Define a custom constructor
function AwesomeMessage(properties) {
    // custom initialization code
    ...
}

// Register the custom constructor with its reflected type (*)
root.lookupType("awesomepackage.AwesomeMessage").ctor = AwesomeMessage;

// Define custom functionality
AwesomeMessage.customStaticMethod = function() { ... };
AwesomeMessage.prototype.customInstanceMethod = function() { ... };

// Continue at "Create a new message" above
```

(\*) 除了参考其反映的类别外,通过 `AwesomeMessage.$type` 财务报告和审定财务报表 `AwesomeMesage#$type`,相应的自定义类自动包含:

-   `AwesomeMessage.create`
-   `AwesomeMessage.encode` 财务报告和审定财务报表 `AwesomeMessage.encodeDelimited`
-   `AwesomeMessage.decode` 财务报告和审定财务报表 `AwesomeMessage.decodeDelimited`
-   `AwesomeMessage.verify`
-   `AwesomeMessage.fromObject`, (中文(简体) ), `AwesomeMessage.toObject` 财务报告和审定财务报表 `AwesomeMessage#toJSON`

之后,此类型的解码信件是 `instanceof AwesomeMessage`。 。 。 .

或者,如果不需要自定义初始化代码,也可以重新使用并扩展内部构造器:

```js
...

// Reuse the internal constructor
var AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage").ctor;

// Define custom functionality
AwesomeMessage.customStaticMethod = function() { ... };
AwesomeMessage.prototype.customInstanceMethod = function() { ... };

// Continue at "Create a new message" above
```

### 使用服务

图书馆也支持消费服务,但并不对实际运输通道作任何假设. 相反,用户必须提供一个合适的 RPC 执行,这是一个同步函数,它以反射的服务方法,二进制请求和节点风格的回调作为其参数:

```js
function rpcImpl(method, requestData, callback) {
    // perform the request using an HTTP request or a WebSocket for example
    var responseData = ...;
    // and call the callback with the binary response afterwards:
    callback(null, responseData);
}
```

下面是一个使用 grpc npm 软件包进行打字程序执行的工作示例 .

```ts
const grpc = require('grpc')

const Client = grpc.makeGenericClientConstructor({})
const client = new Client(
  grpcServerUrl,
  grpc.credentials.createInsecure()
)

const rpcImpl = function(method, requestData, callback) {
  client.makeUnaryRequest(
    method.name,
    arg => arg,
    arg => arg,
    requestData,
    callback
  )
}
```

示例

```protobuf
// greeter.proto
syntax = "proto3";

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}
```

```js
...
var Greeter = root.lookup("Greeter");
var greeter = Greeter.create(/* see above */ rpcImpl, /* request delimited? */ false, /* response delimited? */ false);

greeter.sayHello({ name: 'you' }, function(err, response) {
    console.log('Greeting:', response.message);
});
```

服务还支持承诺:

```js
greeter.sayHello({ name: 'you' })
    .then(function(response) {
        console.log('Greeting:', response.message);
    });
```

还有一个 [用于流媒体 RPC](https://github.com/dcodeIO/protobuf.js/blob/master/examples/streaming-rpc.js)。 。 。 .

注意服务API是针对客户的. 实施服务器端端点几乎总是需要传输通道(即:http,websocket等)的特定代码,唯一的共同点是它解码和编码消息.

### 使用类型脚本

图书馆有自己的船 [类型定义](https://github.com/dcodeIO/protobuf.js/blob/master/index.d.ts) 和现代编辑 [视觉工作室代码](https://code.visualstudio.com/) 将自动检测并用于代码补全.

Npm 软件包取决于 [@ types/ 长](https://www.npmjs.com/package/@types/long) 因为 `Long`。如果您不是为节点而建和/或不使用长的.js,那么手动排除它们应该是安全的.

#### 利用联合来文API

上面显示的API与TypeScript几乎相同. 然而,由于每件事物都是被打入的,在动态生成的信息类实例中访问字段需要使用括号注释(即:. `message["awesomeField"]`)或明确铸造. 或者,可以使用 [为静态对应程序生成的打字文件](https://npmcn.com/package/%40apollo/protobufjs/#readme-pbts-for-typescript)。 。 。 .

```ts
import { load } from "@apollo/protobufjs"; // respectively "./node_modules/protobufjs"

load("awesome.proto", function(err, root) {
  if (err)
    throw err;

  // example code
  const AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage");

  let message = AwesomeMessage.create({ awesomeField: "hello" });
  console.log(`message = ${JSON.stringify(message)}`);

  let buffer = AwesomeMessage.encode(message).finish();
  console.log(`buffer = ${Array.prototype.toString.call(buffer)}`);

  let decoded = AwesomeMessage.decode(buffer);
  console.log(`decoded = ${JSON.stringify(decoded)}`);
});
```

#### 使用生成的静态代码

如果您生成了静态代码到 `bundle.js` 使用 CLI 及其类型定义 `bundle.d.ts`,那么你可以仅仅做:

```ts
import { AwesomeMessage } from "./bundle.js";

// example code
let message = AwesomeMessage.create({ awesomeField: "hello" });
let buffer  = AwesomeMessage.encode(message).finish();
let decoded = AwesomeMessage.decode(buffer);
```

#### 使用装饰器

图书馆还包括尽早实施 [装饰器](https://www.typescriptlang.org/docs/handbook/decorators.html)。 。 。 .

**说明** 在TypeScript中,装饰器是一个实验性特征,而根据JS目标,宣布顺序是重要的. 譬如说, `@Field.d(2, AwesomeArrayMessage)` 要求 `AwesomeArrayMessage` 目标设定时已提前定义 `ES5`。 。 。 .

```ts
import { Message, Type, Field, OneOf } from "@apollo/protobufjs/light"; // respectively "./node_modules/protobufjs/light.js"

export class AwesomeSubMessage extends Message<AwesomeSubMessage> {

  @Field.d(1, "string")
  public awesomeString: string;

}

export enum AwesomeEnum {
  ONE = 1,
  TWO = 2
}

@Type.d("SuperAwesomeMessage")
export class AwesomeMessage extends Message<AwesomeMessage> {

  @Field.d(1, "string", "optional", "awesome default string")
  public awesomeField: string;

  @Field.d(2, AwesomeSubMessage)
  public awesomeSubMessage: AwesomeSubMessage;

  @Field.d(3, AwesomeEnum, "optional", AwesomeEnum.ONE)
  public awesomeEnum: AwesomeEnum;

  @OneOf.d("awesomeSubMessage", "awesomeEnum")
  public which: string;

}

// example code
let message = new AwesomeMessage({ awesomeField: "hello" });
let buffer  = AwesomeMessage.encode(message).finish();
let decoded = AwesomeMessage.decode(buffer);
```

支持的装饰有:

-   **Type.d( 类型名称) : `string`(中文(简体) )**   _(可选)_  
    将一个类作为原生信息类型。 若为 `typeName` 未指定,构造器的运行时函数名用于反射类型.
    
-   **字段.d<T>(字段编号: `number`,字段类型 : `string | Constructor<T>`现场规则 `"optional" | "required" | "repeated"`,默认值 : `T`(中文(简体) )**  
    以指定的 id 和 protobuf 类型表示一个属性作为原生体字段.
    
-   **Map Field.d <T extend { \[key: string\]: 任意 QQ(field Id: `number`字段键盘 : `string`田园瓦鲁埃Type. `string | Constructor<{}>`(中文(简体) )**  
    以指定的 id、 protobuf 密钥和值类型将属性作为原型图域.
    
-   **OneOf.d <T 扩展字符串>(... 字段名称 : `string[]`(中文(简体) )**  
    标注一个财产,作为涵盖指定字段的原型.
    

其他说明:

-   装饰类型 `protobuf.roots["decorated"]` 使用平面结构,所以没有重复名称.
-   Enums被复制到一个反射的enum上,在装饰器评价上有一个通用名称,因为被引用的enum对象没有装饰器可以使用的运行时名.
-   默认值必须指定为给装饰者的参数,而不是使用属性初始化器进行适当的原型行为.
-   装饰类上的财产名不得在编译时间上被重新命名(即由修饰器重命名),因为装饰者只是作为字符串接收了原字段名.

**准备!** 没有那么漂亮,但你可以 [使用纯 JavaScript 中的装饰器](https://github.com/dcodeIO/protobuf.js/blob/master/examples/js-decorators.js) 还有.

## 命令行

**说明** 移动 CLI 到 [其自己的软件包](https://npmcn.com/package/%40apollo/protobufjs/cli) 这是一项正在进行的工作。 目前仍属于主包.

命令行界面(CLI)可用于文件格式之间的翻译并生成静态代码以及TypeScript定义.

### 用于 Java 脚本的 pbjs

```
Translates between file formats and generates static code.

  -t, --target     Specifies the target format. Also accepts a path to require a custom target.

                   json          JSON representation
                   json-module   JSON representation as a module
                   proto2        Protocol Buffers, Version 2
                   proto3        Protocol Buffers, Version 3
                   static        Static code without reflection (non-functional on its own)
                   static-module Static code without reflection as a module

  -p, --path       Adds a directory to the include path.

  -o, --out        Saves to a file instead of writing to stdout.

  --sparse         Exports only those types referenced from a main file (experimental).

  Module targets only:

  -w, --wrap       Specifies the wrapper to use. Also accepts a path to require a custom wrapper.

                   default   Default wrapper supporting both CommonJS and AMD
                   commonjs  CommonJS wrapper
                   amd       AMD wrapper
                   es6       ES6 wrapper (implies --es6)
                   closure   A closure adding to protobuf.roots where protobuf is a global

  -r, --root       Specifies an alternative protobuf.roots name.

  -l, --lint       Linter configuration. Defaults to protobuf.js-compatible rules:

                   eslint-disable block-scoped-var, no-redeclare, no-control-regex, no-prototype-builtins

  --es6            Enables ES6 syntax (const/let instead of var)

  Proto sources only:

  --keep-case      Keeps field casing instead of converting to camel case.

  Static targets only:

  --no-create      Does not generate create functions used for reflection compatibility.
  --no-encode      Does not generate encode functions.
  --no-decode      Does not generate decode functions.
  --no-verify      Does not generate verify functions.
  --no-convert     Does not generate convert functions like from/toObject
  --no-delimited   Does not generate delimited encode/decode functions.
  --no-beautify    Does not beautify generated code.
  --no-comments    Does not output any JSDoc comments.

  --force-long     Enforces the use of 'Long' for s-/u-/int64 and s-/fixed64 fields.
  --force-number   Enforces the use of 'number' for s-/u-/int64 and s-/fixed64 fields.
  --force-message  Enforces the use of message instances instead of plain objects.

usage: pbjs [options] file1.proto file2.json ...  (or pipe)  other | pbjs [options] -
```

对于生产环境,建议将您所有.proto文件捆绑到一个单一的.json文件中,这将最小化网络请求的数量并避免任何解析器上浮(int:仅使用 **光线** 库 :

```
$> pbjs -t json file1.proto file2.proto > bundle.json
```

现在,要么把这个文件纳入您的最后捆绑:

```js
var root = protobuf.Root.fromJSON(require("./bundle.json"));
```

或按通常方式装入:

```js
protobuf.load("bundle.json", function(err, root) {
    ...
});
```

生成的静态代码, 另一方面,工作与只有 **最小** 图书馆。 举个例子

```
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
```

将生成内部定义的静态代码 `file1.proto` 财务报告和审定财务报表 `file2.proto` 改为通用JS模块 `compiled.js`。 。 。 .

**准备!** 记录您的 . proto 文件 `/** ... */`\- 块或(拖动) `/// ...` 线条翻译为生成的静态代码.

### 类型脚本的 pbts

```
Generates TypeScript definitions from annotated JavaScript files.

  -o, --out       Saves to a file instead of writing to stdout.

  -g, --global    Name of the global object in browser environments, if any.

  --no-comments   Does not output any JSDoc comments.

  Internal flags:

  -n, --name      Wraps everything in a module of the specified name.

  -m, --main      Whether building the main library without any imports.

usage: pbts [options] file1.js file2.js ...  (or)  other | pbts [options] -
```

从上面的例子来看,下面不仅生成一个普通JS模块的静态代码 `compiled.js` 及其相应的类型脚本定义 `compiled.d.ts`数字 :

```
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
$> pbts -o compiled.d.ts compiled.js
```

此外,静态模块的TypeScript定义与基于反射的对等模块(即由JSON模块导出)相兼容,只要满足以下条件: 1

1.  而不是使用 `new SomeMessage(...)`,总是使用 `SomeMessage.create(...)` 因为反射对象不提供构建器.
2.  类型、服务和enums必须从大写字母入手,才能作为所反映类型的属性(即能够使用) `MyMessage.MyEnum` 改为 `root.lookup("MyMessage.MyEnum")`) (中文(简体) ).

例如,以下生成一个 JSON 模块 `bundle.js` (单位:千美元) `bundle.d.ts`,但没有静态代码 :

```
$> pbjs -t json-module -w commonjs -o bundle.js file1.proto file2.proto
$> pbjs -t static-module file1.proto file2.proto | pbts -o bundle.d.ts -
```

### 反射对静态代码

在使用.proto文件时,直接要求完整库分别纯反射/JSON光光库,几乎所有代码,但相对短的描述符被共享.

另一方面,静态代码只需要最小的库,但生成没有任何反射特性的额外源代码. 这还意味着,当生成的代码数量超过完整的光库大小后,静态生成的代码就会比以描述符为基础的代码大出一个断点.

性能方面没有显著差异,因为静态生成的代码与运行时生成的代码基本相同,而且如上一节所见,两者基本上可以互换.

| 来源 | 图书馆 | 优点 | 权衡 |
| --- | --- | --- | --- |
| . proto (中文(简体) ) | 满 | 易于编辑  
与其他图书馆的互通性  
没有编译步骤 | 一些解析和可能的网络间接费用 |
| 贾森 | 光线 | 易于编辑  
没有分析间接费用  
单装( 无网络管理) | 特有原型  
有汇编步骤 |
| 静态 | 最小 | 工作地点 `eval` 访问受到限制  
完整记录  
小原生物的小脚印 | 可能很难编辑  
无反省  
有汇编步骤 |

### 命令行 API

通过提供命令行参数和回调,这两种公用事业都可以在方案上使用 `main` 函数:

```js
var pbjs = require("@apollo/protobufjs/cli/pbjs"); // or require("@apollo/protobufjs/cli").pbjs / .pbts

pbjs.main([ "--target", "json-module", "path/to/myproto.proto" ], function(err, output) {
    if (err)
        throw err;
    // do something with output
});
```

## 其他文件

#### 协议缓冲

-   [Google 开发者指南](https://developers.google.com/protocol-buffers/docs/overview)

#### (原始内容存档于2012-10-12). protobuf.js

-   [API 文档](https://protobufjs.github.io/protobuf.js)
-   [变化](https://github.com/dcodeIO/protobuf.js/blob/master/CHANGELOG.md)
-   [经常问的问题](https://github.com/dcodeIO/protobuf.js/wiki) 我们的维基百科

#### 社区

-   [问答](http://stackoverflow.com/search?tab=newest&q=protobuf.js) 在堆叠叠流上

## 业绩

该套装包括一个基准,将protobuf.js的性能与本地的JSON(尽可能这样做)进行比较;以及 [谷歌的JS执行](https://github.com/google/protobuf/tree/master/js)在运行的i7-2600K节点6.9.1上,它产生:

```
benchmarking encoding performance ...

protobuf.js (reflect) x 541,707 ops/sec ±1.13% (87 runs sampled)
protobuf.js (static) x 548,134 ops/sec ±1.38% (89 runs sampled)
JSON (string) x 318,076 ops/sec ±0.63% (93 runs sampled)
JSON (buffer) x 179,165 ops/sec ±2.26% (91 runs sampled)
google-protobuf x 74,406 ops/sec ±0.85% (86 runs sampled)

   protobuf.js (static) was fastest
  protobuf.js (reflect) was 0.9% ops/sec slower (factor 1.0)
          JSON (string) was 41.5% ops/sec slower (factor 1.7)
          JSON (buffer) was 67.6% ops/sec slower (factor 3.1)
        google-protobuf was 86.4% ops/sec slower (factor 7.3)

benchmarking decoding performance ...

protobuf.js (reflect) x 1,383,981 ops/sec ±0.88% (93 runs sampled)
protobuf.js (static) x 1,378,925 ops/sec ±0.81% (93 runs sampled)
JSON (string) x 302,444 ops/sec ±0.81% (93 runs sampled)
JSON (buffer) x 264,882 ops/sec ±0.81% (93 runs sampled)
google-protobuf x 179,180 ops/sec ±0.64% (94 runs sampled)

  protobuf.js (reflect) was fastest
   protobuf.js (static) was 0.3% ops/sec slower (factor 1.0)
          JSON (string) was 78.1% ops/sec slower (factor 4.6)
          JSON (buffer) was 80.8% ops/sec slower (factor 5.2)
        google-protobuf was 87.0% ops/sec slower (factor 7.7)

benchmarking combined performance ...

protobuf.js (reflect) x 275,900 ops/sec ±0.78% (90 runs sampled)
protobuf.js (static) x 290,096 ops/sec ±0.96% (90 runs sampled)
JSON (string) x 129,381 ops/sec ±0.77% (90 runs sampled)
JSON (buffer) x 91,051 ops/sec ±0.94% (90 runs sampled)
google-protobuf x 42,050 ops/sec ±0.85% (91 runs sampled)

   protobuf.js (static) was fastest
  protobuf.js (reflect) was 4.7% ops/sec slower (factor 1.0)
          JSON (string) was 55.3% ops/sec slower (factor 2.2)
          JSON (buffer) was 68.6% ops/sec slower (factor 3.2)
        google-protobuf was 85.5% ops/sec slower (factor 6.9)
```

这些成果是通过下列方式取得的:

-   在运行时生成特定类型编码器、解码器、核查器和转换器
-   根据环境配置读者/作家界面
-   在有利和当然有利的情况下使用特定节点功能
-   通过拆分避免不必要的操作 [工具盘](https://npmcn.com/package/%40apollo/protobufjs/#readme-toolset)。 。 。 .

您也可以运行 [基准](https://github.com/dcodeIO/protobuf.js/blob/master/bench/index.js) .

```
$> npm run bench
```

财务报告和审定财务报表 [配置器](https://github.com/dcodeIO/protobuf.js/blob/master/bench/prof.js) 自己(后者需要最新版本的节点):

```
$> npm run prof <encode|decode|encode-browser|decode-browser> [iterations=10000000]
```

请注意,截至此写作时,基准套件在节点7.2.0上的性能明显慢于6.9.1,因为有蛾.

## 兼容性

-   除了IE8之外,其他所有现代和非现代浏览器都有工作.
-   因为这个包的内部不依赖 `google/protobuf/descriptor.proto`,选项被解析并按字面形式呈现.
-   如果打入的数组没有环境支持,则会取而代之地使用平面数组.
-   对ES5前期环境的支持(IE8除外)可以通过 [使用多填充器](https://github.com/dcodeIO/protobuf.js/blob/master/scripts/polyfill.js)。 。 。 .
-   支助 [内容安全政策](https://w3c.github.io/webappsec-csp/)\- 限制环境(如Chrome扩展,不包含 [不安全的- eval](https://developer.chrome.com/extensions/contentSecurityPolicy#relaxing-eval))可以通过生成和使用静态代码实现.
-   如果需要用64位值(int64, int64等)的正确工作方式,只需安装 [长. js](https://github.com/dcodeIO/long.js) 和这个图书馆一起 全部64位数字将返回为 `Long` 实例,而不是一个可能不安全的 JavaScript 号码([见](https://github.com/dcodeIO/long.js)) (中文(简体) ).
-   关于描述符.proto互操作性,参见: [分机/说明](https://github.com/dcodeIO/protobuf.js/tree/master/ext/descriptor)

## 大楼

要自己建库或其组件, 请从 GitHub 复制并安装开发依赖性 :

```
$> git clone https://github.com/dcodeIO/protobuf.js.git
$> cd protobuf.js
$> npm install
```

利用各自的原始地图建立相应的开发和制作版本 `dist/`数字 :

```
$> npm run build
```

建立文档 `docs/`数字 :

```
$> npm run docs
```

将类型脚本定义构建到 `index.d.ts`数字 :

```
$> npm run types
```

### 浏览整合

默认情况下,protobuf.js在任何浏览器中集成构建过程而不需要任何可选模块. 因此:

-   如果需要Int64支持,则明确要求 `long` 模块在您的项目中某处, 否则它将被排除在外 。 这假设一个全球性的 `require` 函数是存在的,protobuf.js可以调用以获取长模块.
    
    如果没有全球 `require` 在捆绑后出现的函数,也可以在程序上指定长模块:
    
    ```js
    var Long = ...;
    
    protobuf.util.Long = Long;
    protobuf.configure();
    ```
    
-   如果你有任何特别的要求,有 [捆绑器](https://github.com/dcodeIO/protobuf.js/blob/master/scripts/bundle.js) 供参考.
    

**许可证 :** [BSD 3- 标签许可证](https://opensource.org/licenses/BSD-3-Clause)

## 常见问题

### @apollo/protobufjs 是什么？

JavaScript\( & TypeScript\) 协议缓冲器 \.

### 如何安装 @apollo/protobufjs？

在项目目录运行 npm install @apollo/protobufjs，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 apollo-pbjs、apollo-pbts，可以用 npx apollo-pbjs 直接运行。

### @apollo/protobufjs 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @apollo/protobufjs 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @apollo/protobufjs 可以商用吗？

@apollo/protobufjs 使用 BSD-3-Clause 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。另外不得用原作者名义为衍生产品背书。以上为概括，不构成法律意见，请以许可原文为准。

### @apollo/protobufjs 的下载量有多少？

根据 npm 官方下载统计，@apollo/protobufjs 在 2026/10/07 – 2026/11/05 这 30 天内被下载 18,006,593 次，日均约 600,220 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @apollo/protobufjs 还在维护吗？

最新版本 1\.2\.8 发布于 2026/05/01（6 个月前）；至今共发布 17 个版本，其中过去 12 个月发布了 1 个；首次发布于 2019/11/20。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

