TypeScript对于习惯强类型语言(比如Unity C#)而又要写JavaScript项目(比如CocosCreator Egret)的程序员来说,确实提供了很大方便,而且对于一些由于弱类型语言导致的只能运行时检查的低级错误,使用TS都能很好的避免。
这次要记录的是使用TypeScript作为主开发语言的CocosCreator项目中引用第三方库的方法和问题,实测的是MessagePack,protobufjs和Photon这几个库。
首先是MessagePack,这个用了最无脑的npm包方式,虽然新版本的Creator(我写这篇博文的时候用的是v2.1.0)已经号称不支持npm方式引用第三方库(据说从1.6开始,http://forum.cocos.com/t/1-6-npm/49926),但实测直接以node npm方式在项目根目录下添加package.json并指定第三方库还是可以正常工作的,当然如论坛里官方人员说的,这样确实会带来某些弊端,比如依赖之类的,但毫无疑问npm管理第三方js库是最方便的。对于MsgPack,package.json可以直接手写如下:
1 2 3 4 5 6 7 8 | { "name" : "" , "version" : "" , "dependencies" : { "@types/msgpack-lite" : "^0.1.6" , "msgpack-lite" : "^0.1.26" } } |
也可以npm install -S方式,这样完成后还会直接安装ts需要的.d接口定义,直接在Creator .ts里使用即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import * as msgpack from "msgpack-lite" ; const { ccclass, property } = cc._decorator; @ccclass export default class Helloworld extends cc.Component { @property(cc.Label) label: cc.Label = null ; @property text: string = 'hello' ; start() { // init logic this .label.string = this .text; const temp = msgpack.encode({ test: "asdasd" }); console.log( ">>>>" , temp); const dtemp = msgpack.decode(temp); console.log( "<<<<<" , dtemp); } } |
下一个是Photon JS库,这个就没有npm包方式了,只有官网提供的Download SDK方式下载:https://www.photonengine.com/en-us/sdks#realtimejavascript,这个就要按照Creator目前官方推荐的方式引入了:https://docs.cocos.com/creator/manual/zh/scripting/plugin-scripts.html,由于不需要调试或读js源码,接口有ts定义,所以直接复制下载好的Photon JS库中的Photon-Javascript_SDK.min.js和Photon-Javascript_SDK.d.ts到Creator项目中,并且标记插件脚本即可:
由于这种方式,Creator会将插件脚本进行全局化处理,因此不用像MsgPack那样再做import,直接使用即可(实测VSCode这样基于ts定义的感知也可正常工作):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | this ._photonLBC = new Photon.LoadBalancing.LoadBalancingClient( Photon.ConnectionProtocol.Ws, appId, ConstData.CLIENT_VER ); this ._photonLBC.onStateChange = (state: number) => { cc.log( "LBC onStateChange: " + state); const sceneMain = cc.find( "Canvas" ).getComponent(SceneMain); const LBCState = Photon.LoadBalancing.LoadBalancingClient.State; switch (state) { case LBCState.ConnectedToNameServer: sceneMain.outputLog( "已连接NameServer!" ); break ; case LBCState.ConnectedToMaster: sceneMain.outputLog( "已连接Master!" ); break ; case LBCState.JoinedLobby: sceneMain.outputLog( "已加入Lobby!" ); break ; case LBCState.Joined: break ; case LBCState.Disconnected: sceneMain.outputLog( "已断开连接!" ); break ; default : cc.warn(`LBC state not handled: ${state}`); break ; } }; |
最后是Protobuf,这个在之前的js项目中也用到过了,而且百度下相关资料一大把,各种引入方式,各种使用方式,proto生成js文件的,直接使用proto动态解析的,并且刚才给出的官方文档里,也以protobufjs为例进行了说明:
如果插件还依赖于其它插件,也需要把多个插件合并为单个 js 文件
以 protobuf.js 为例,这个库还依赖于 bytebuffer.js,但是插件作者并没有提供整合好的独立运行版本。我们可以先下载到这两个库各自编译后的两个文件 protobuf.js 和 bytebuffer.js,然后使用文本编辑器或类似cat
这样的命令行工具将这两个脚本拼合成一个新的脚本 protobuf_all.js。然后就能在 Creator 中直接使用这个 protobuf_all.js 了。
现在新release的6.x已经不需要再手动做这个整合操作了,直接将pbjs作者提供好的protobuf.min.js和index.d.ts改名为protobuf.d.ts一起复制进项目,然后如法炮制设置插件脚本,这样都设置好以后,会发现并没有像刚才Photon那样开箱即用,而会收到这么个错误:
‘protobuf’ refers to a UMD global, but the current file is a module. Consider adding an import instead.ts(2686)
一通查之后,发现问题在于protobuf.d.ts中的namespace声明方式,其实直接无视这个lint错误,在编译到js状态时运行还是不会出错的,但这样一来代码里一直有错误提示,二来ts的大优势,代码感知protobuf相关的就用不了了,所以解决方法是修改下.d.ts,在最外层像Photon库一样使用declare module方式声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | // export as namespace protobuf; declare module protobuf { /** * Provides common type definitions. * Can also be used to provide additional google types or your own custom types. * @param name Short name as in `google/protobuf/[name].proto` or full file name * @param json JSON definition within `google.protobuf` if a short name, otherwise the file's root definition */ export function common(name: string, json: { [k: string]: any }): void; export namespace common { /** Properties of a google.protobuf.Any message. */ interface IAny { typeUrl?: string; bytes?: Uint8Array; } ... /** * An allocator as used by {@link util.pool}. * @param size Buffer size * @returns Buffer */ type PoolAllocator = (size: number) => Uint8Array; /** * A slicer as used by {@link util.pool}. * @param start Start offset * @param end End offset * @returns Buffer slice */ type PoolSlicer = ( this : Uint8Array, start: number, end: number) => Uint8Array; } |
这样修改以后,ts使用时就不会报错了,也可以正常感知protobufjs相关api了。
博主友情提示:
如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。
加载更多