Flutter Protocol Buffers生成插件better_protoc_plugin的使用

Flutter Protocol Buffers生成插件better_protoc_plugin的使用

better_protoc_plugin

An opinionated, “new and improved” protobuf protoc compiler plugin used to generate Dart code with real Dart enums, message interfaces, automatic DateTime/Duration conversion, etc.

TLDR: Usage

最简单的方式,如果全局激活:

dart pub global activate better_protoc_plugin

# => Activated better_protoc_plugin 1.2.2

cd $HOME/myproject

# 注意 `better_protos` 选项以及 `gprc:path...`。
# 假设 .proto 文件在 `$HOME/myproject/proto` 中。
# 你必须显式包含任何 `google/protobuf/.proto` 文件,
# 因为不幸的是 `protoc` 不理解这些文件上的通配符。
protoc --dart_out=better_protos,grpc:path/to/generated \
    -Iproto \
    proto/* \
    -I$HOME/myproject/proto \
    $HOME/myproject/proto/* \
    google/protobuf/timestamp.proto \
    google/protobuf/duration.proto

从源码开始,如果从GitHub克隆到 $HOME/better_protoc_plugin

cd $HOME/better_protoc_plugin

make

cd $HOME/myproject

# 注意 `better_protos` 选项以及 `gprc:path...`。
# 假设 .proto 文件在 `$HOME/myproject/proto` 中。
# 你必须显式包含任何 `google/protobuf/.proto` 文件,
# 因为不幸的是 `protoc` 不理解这些文件上的通配符。
protoc --plugin=$HOME/better_protoc_plugin/bin/protoc-gen-dart \
    --dart_out=better_protos,grpc:path/to/generated \
    --proto_path=$HOME/better_protoc_plugin/protos \
    -Iproto \
    proto/* \
    -I$HOME/myproject/proto \
    $HOME/myproject/proto/* \
    google/protobuf/timestamp.proto \
    google/protobuf/duration.proto

Latest merged google/protobuf.dart upstream commit

LATEST_UPSTREAM_COMMIT=96d9522

要比较:

$ make compare-upstream

合并更改后,在Makefile和README中更新 LATEST_UPSTREAM_COMMIT 变量以指向最新的提交。注意:我们只关心上游仓库的 protoc_plugin 子目录(作为git子模块添加到此项目中以便于比较)。

Forked from Google's protoc_plugin v22.0.0-dev @96d9522

前提:创建此分支的原因是为了使使用 protobuf 在Dart后端或ORM中更容易,通过生成接口,因为创建单独的数据库模型定义而没有接口类型安全性的额外工作和错误容易发生。嘿,protoc_plugin 甚至可以为你生成后端服务和客户端存根!为什么不做到极致呢?

此分支通过添加接口类、其他便利包装器/转换器以及解决多个其他开放问题来改进生成器,而不改变基础协议。

  • 每个消息生成额外的 abstract interface class,带有类型化的getter:

    • 接口名称前缀为 I
    • 对于实现强类型的ORM类很有用;
  • dart:core.DateTimedart:core.Duration 的setter/getter以及 protobuf.Timestampprotobuf.Duration 字段的转换(google/protobuf.dart#792):

    • DateTime 使用内置的protobuf TimeStampMixin 转换器;
  • Dart null 安全性(可选字段)用于非必需/存在字段,带有getter/setter包装器(google/protobuf.dart#493):

    • getter 使用 has{Field}() 来检查存在性;
    • 将字段设置为 null 会调用 clearField()
    • 不用于必需/非存在、重复或映射字段;
  • 真正的 Dart enums 而不是带有静态常量的类(google/protobuf.dart#862):

    • 生成正确的 Dart camelCase 枚举值,并支持从/到 CONSTANT_CASE 的protobuf值转换(google/protobuf.dart#372);

Bugfixes / PRs welcomed.

请,Google Dart/Flutter团队,看到一些这些功能在 官方 Dart protoc生成器中会很棒。

我会尝试拉取任何生成器更改/改进来自 google/protobuf.dart。希望最终我们会看到更好的Dart接口、可选项、枚举和原生类型转换支持,以便更轻松地使用protobuf与Dart后端及ORM结合。

我打算在此期间保持更新并将其用于生产项目。

Testing

$ dart pub get
$ make run-tests

Original protoc_plugin README:

此存储库提供了Dart插件,用于 protoc编译器。它生成用于处理协议缓冲区格式数据的Dart文件。

Requirements

要编译 .proto 文件,你必须使用单独安装的 protoc 命令。protoc 3.0.0或更高版本是必需的。

生成的文件是纯Dart代码,可以在Dart VM或浏览器中运行(使用dart2js)。它们依赖于protobuf Dart包。一个包括生成文件的Dart项目应该在 pubspec.yaml 文件中添加 protobuf 作为依赖项。

How to build

确保你的 PATH 中有 dart 可执行文件。详情见 Dart安装说明

如果你在遵循以下说明时遇到任何问题,请确保你安装了最新版本的Dart。

推荐方法 是激活最新发布的插件版本:

$ dart pub global activate protoc_plugin

确保 ~/.pub-cache/bin 在你的 PATH 中。

这种方法安装了一个Dart脚本,并且需要你的 PATH 中存在 dart 可执行文件。

从源码构建:

  • protoc_plugin 目录中运行 dart pub get
  • protoc_plugin/bin 添加到你的 PATH 中,或者将路径传递给 protoc_plugin/bin/protoc-gen-dartprotoc--plugin 选项。

protoc-gen-dart 可执行文件是一个Dart脚本,并且需要你的 PATH 中存在 dart 可执行文件。

从源码构建独立可执行文件:

  • protoc_plugin 中运行 dart pub get
  • 使用 dart compile exe bin/protoc_plugin.dartprotoc_plugin 中构建独立可执行文件

生成的可执行文件不需要 dart 可执行文件即可运行。你应该将生成的可执行文件 protoc_plugin/bin/protoc_plugin.exe 复制到你的 PATH 并命名为 protoc-gen-dart,或者在调用 protoc 时将该路径传递给 protoc--plugin 选项。

How to use

一旦你有了 protoc-gen-dartPATH 中,你可以像这样调用协议缓冲区编译器来为 test.proto 文件生成Dart代码:

$ protoc --dart_out=. test.proto

如果你不想将 protoc-gen-dart 添加到 PATH 中,你可以像这样指定路径:

$ protoc --dart_out=. test.proto --plugin=<path to plugin executable>

Options to control the generated Dart code

协议缓冲区编译器接受每个插件的选项。对于Dart插件,这些选项与 --dart_out 选项一起传递。各个选项使用逗号分隔,最后的输出指令与选项使用冒号分隔。传递选项 <option 1><option 2> 如下所示:

--dart_out="<option 1>,<option 2>:."

Generating grpc Headers

要为 grpc 生成代码,你需要传递 grpc 选项:

--dart_out="grpc:."

Generating Code Info

该插件包括 generate_kythe_info 选项,如果在运行时传递,将使插件生成元数据文件,这些文件与为proto消息及其枚举生成的 .dart 文件一起生成。将此选项与其他dart_out选项一起传递:

--dart_out="generate_kythe_info,<other options>:."

Using protocol buffer libraries to build new libraries

协议缓冲区编译器为每个编译的 .proto 文件生成多个文件。有时这并不完全符合需求,例如有人可能想创建新的库,公开这些库中的对象,或将几个 .proto 库中的对象定义组合成一个新库。

最佳的方法是创建所需的新的库,并重新导出相关的协议缓冲区类。

假设我们有一个名为 m1.proto 的文件,内容如下:

syntax = "proto3";

message M1 {
  string a = 1;
}

以及一个名为 m2.proto 的文件,内容如下:

syntax = "proto3";

message M2 {
  string b = 1;
}

编译这些文件到Dart将会产生两个库,分别位于 m1.pb.dartm2.pb.dart。以下代码展示了一个库 M,它结合了这两个协议缓冲区库,公开了 M1M2 类,并添加了一些附加方法。

library M;

import "m1.pb.dart";
import "m2.pb.dart";

export "m1.pb.dart" show M1;
export "m2.pb.dart" show M2;

M1 createM1() => new M1();
M2 createM2() => new M2();

更多关于Flutter Protocol Buffers生成插件better_protoc_plugin的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Protocol Buffers生成插件better_protoc_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用better_protoc_plugin来生成Protocol Buffers代码的示例。better_protoc_plugin是一个Dart插件,用于从.proto文件生成Dart代码,从而可以在Flutter应用中使用Protocol Buffers。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加better_protoc_plugin的依赖:

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  build_runner: ^2.0.0
  better_protoc_plugin: ^0.0.1+2  # 请检查最新版本号

注意:版本号可能会更新,请查看pub.dev上的最新版本。

2. 创建.proto文件

在项目的根目录下创建一个名为example.proto的文件,内容如下:

syntax = "proto3";

package example;

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

3. 配置build.yaml

在项目根目录下创建或编辑build.yaml文件,添加以下内容来配置better_protoc_plugin

targets:
  $default:
    builders:
      better_protoc_plugin:
        generate_for:
          - example/**.proto
        options:
          plugin: protoc-gen-dart=bin/protoc-gen-dart

注意:protoc-gen-dart的路径可能需要根据你的系统配置进行调整。确保protoc-gen-dart可执行文件在你的PATH中,或者指定正确的路径。

4. 生成Dart代码

打开终端,导航到你的Flutter项目根目录,然后运行以下命令来生成Dart代码:

flutter pub run build_runner build

这将读取example.proto文件并使用better_protoc_plugin生成相应的Dart代码。生成的代码通常会放在lib/generated目录下(这个目录可以根据配置调整)。

5. 使用生成的代码

生成的Dart代码会包含与你的.proto文件对应的类。例如,对于上面的example.proto文件,你会得到一个Person类。你可以在你的Flutter应用中使用这个类:

import 'package:your_project_name/generated/example/example.pb.dart';

void main() {
  Person person = Person()
    ..name = 'John Doe'
    ..id = 1234
    ..email = 'johndoe@example.com';

  // 这里你可以进行序列化和反序列化等操作
  List<int> byteData = person.writeToBuffer();
  Person deserializedPerson = Person.fromBuffer(byteData);

  print('Name: ${deserializedPerson.name}');
  print('ID: ${deserializedPerson.id}');
  print('Email: ${deserializedPerson.email}');
}

注意:将your_project_name替换为你的实际项目名称,并确保路径正确指向生成的.pb.dart文件。

通过以上步骤,你应该能够在Flutter项目中成功使用better_protoc_plugin来生成和使用Protocol Buffers代码。

回到顶部