首先我的proto文件结构如下图


image.png

按照这样的proto文件夹结构生成对应go/js/ts 代码的话,message 相互调用是不可避免的,而golang 的导入 import和protobufjs的导入的 import是不一样的。

例如:Golang:

import "common/models/user/user.proto";

而 protobufjs 按照这样的 import 导入是找不到 user.proto文件的,所以我们需要把 import改为一个相对路径,如下

import "../user/user.proto";

再次执行 pbjs -t static-module -w commonjs -o chat.js chat.proto 就没有找不到 user.proto的错误了。

当然除此之外也可以把所有 proto文件放在一个文件夹内,用生成所有的proto 文件命令也不会报错。pbjs -t static-module -w commonjs -o all.js *.proto

以上两种方式生成完毕后还需要手动去修改几个地方才可以再cc 中使用

1.修改生成的js文件中的$protobufjs和root

原:var $protobuf = require("protobufjs/minimal");修改为:var $protobuf = protobuf;原:var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});修改为:const $root = $protobuf.roots.creator3 || ($protobuf.roots.creator3 = $util.global);

2.如果你的proto文件中有 uint64/int64的变量时需要在ts文件导入 long

import { Long } from "protobufjs";

3.解决proto中引用问题

生成的ts源文件为:import * as $protobuf from "protobufjs";export namespace user {
  //省略中间代码}修改为import * as $protobuf from "protobufjs";import { Long } from "protobufjs";declare global {
  export namespace user {
  //省略中间代码
  }}export { user as default };

最后代码中使用

let msg = user.LoginReq.create({LoginName: username, LoginPW: password})
let buffer = user.LoginReq.encode(msg).finish()
let sendData = ProtocolUtils.getInstance().getDataPack(1002, buffer)
NetManager.getInstance().send(sendData)

最后在将上述操作写为脚本
下面的两个shell 脚本路径是和我首图项目中的common处于同级,另外是用于mac,其他操作系统可能有些函数的不兼容,需要自己做下修改
Golang:

# shellcheck disable=SC2239

#!bin/sh
function deleteGoFile(){
  for file in `ls $1`
  do
     if [ -d $1"/"$file ]
       then
        deleteGoFile $1"/"$file
     else
        if [ "${file##*.}" = "go" ]
          then
            rm -f $1"/"$file
        fi
   fi
  done
}

function addGoFile(){
  for file in `ls $1`
  do
     if [ -d $1"/"$file ]
       then
        addGoFile $1"/"$file
     else
        if [ "${file##*.}" = "proto" ]
           then
             echo $1"/"$file
           protoc --go_out=. $1"/"$file
        fi
   fi
  done
}
deleteGoFile common/models
addGoFile common/models

cocos creator

# shellcheck disable=SC2239

#!bin/sh
function cpDirs(){
  for file in `ls $1`
    do
    cp -r $1"/"$file "/Users/luffy/Desktop/ts_protos"
  done
}

resetProtoFileContent(){
  for file in `ls $1`
      do
      if [ -d $1"/"$file ]
         then
            resetProtoFileContent $1"/"$file
         else
              if [ "${file##*.}" = "proto" ]
                 then
                   #注意这里是mac的sed用法
                sed -i '' 's/import "common\/models/import "../g' $1"/"$file
              fi
      fi
    done
}


function addJsFile(){
  for file in `ls $1`
  do
     if [ -d $1"/"$file ]
       then
        addJsFile $1"/"$file
     else
        if [ "${file##*.}" = "proto" ]
           then
            cd $1 && pbjs -t static-module -w commonjs -o ${file%.*}".js" $file
        fi
   fi
  done
}

function addTsFile(){
  for file in `ls $1`
  do
     if [ -d $1"/"$file ]
       then
        addTsFile $1"/"$file
     else
        if [ "${file##*.}" = "proto" ]
           then
            cd $1 && pbts -o ${file%.*}".d.ts" ${file%.*}".js"
        fi
   fi
  done
}

function resetJsFileContent() {
     for file in `ls $1`
      do
         if [ -d $1"/"$file ]
           then
            resetJsFileContent $1"/"$file
         else
            if [ "${file##*.}" = "js" ]
               then
                sed -i '' 's/require("protobufjs\/minimal");/protobuf;/g' $1"/"$file
                sed -i '' '10d' $1"/"$file
                sed -i '' '10i\
const $root = $protobuf.roots.creator3 || ($protobuf.roots.creator3 = $util.global);\
' $1"/"$file
                sed -i '' '$d' $1"/"$file
            fi
       fi
      done
}

function resetTsFileContent() {
     for file in `ls $1`
      do
         if [ -d $1"/"$file ]
           then
            resetTsFileContent $1"/"$file
         else
            if [ "${file##*.}" = "ts" ]
               then
                  sed -i '' '2i\
import { Long } from "protobufjs";\
\
declare global {\
\
' $1"/"$file

                  sed -i '' "\$a\\
}\\
\\
export {${1##*/} as default};"  $1'/'$file

            fi
       fi
      done
}

#在桌面创建一个中间文件夹 生成js/ts
rm -rf /Users/luffy/Desktop/ts_protos
mkdir /Users/luffy/Desktop/ts_protos
cpDirs common/models
resetProtoFileContent /Users/luffy/Desktop/ts_protos #修改原proto文件 import 为相对路径
addJsFile /Users/luffy/Desktop/ts_protos
resetJsFileContent /Users/luffy/Desktop/ts_protos
addTsFile /Users/luffy/Desktop/ts_protos
resetTsFileContent /Users/luffy/Desktop/ts_protos

最后将生成的ts / js文件拖入cocos creator 中就行了。
顺便说一下,这样的情况 ts 文件会报错,原因是有引用其他包message,也会在当前ts 文件中写出来。可以不用去管它,不影响项目,也可以手动或者在脚本中删除。

点赞(489)

评论列表共有 0 条评论

立即
投稿
返回
顶部