首先我的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 文件中写出来。可以不用去管它,不影响项目,也可以手动或者在脚本中删除。
发表评论 取消回复