CocosCreator JavaScript/TypeScript混编

为什么要混编

首先,如果一个新的项目,能ts就ts了。其实也用不着混编了。但是搁不住有本身是js的项目。在或者起初对ts不了解。首先用了js,后来想改,但是项目规模上来了。全篇修改太困难。现在想用ts的类型提示的便利,有懒得去修改之前的老旧代码。那么知道一些混编的技巧就很重要了。

全局变量/函数

之前直接定义在window里面的变量和方法,在ts里面直接用是没问题的。但是VSCode会给出红线提示。十分碍眼。直接写window.Xxx,会显示没有这个变量的红线。因此应用globalThis.代替window.:

globalThis.NotificationCenter.pushNotification('as_fadeOut');

还可以在所需要文件开头就把需要用到的原window.下面的内容定义在文件范围内的同名变量下:

let NotificationCenter = globalThis.NotificationCenter;

总之globalThis就是TS里面声明类型为any的window.

如果是针对微信小游戏,在发布到微信开发者工具后,微信开发者工具对globalThis无法识别会导致错误,而且报出其它的莫名其妙的错误。需要针对微信小游戏平台进行一个简单的适配:

if (window.wx != null) {
	window.globalThis = window;
}

放在一开始就好了,其它调用的地方该怎么写还是怎么写不变。

TS中类型引用到全局,以及对象的单例模式

但是TS类放到全局的时候我依然习惯了window,引用对象的获取也习惯使用单例:
这里BaseView是继承自cc.Component的。
如果是个prefab,很明显,在这个node被指定parent的时候,单例对象开始存在了。

@ccclass
export default class GameData extends BaseView {
    private static _instance: GameData = null;
    public static getInstance(): GameData {
        return this._instance;
    }
    constructor() {
        super();
        GameData._instance = this;
    }
    // ...
}
(<any>window).GameData = GameData;

这样使用单例:(不论ts还是js都一样)

GameData.getInstance().totalTrophy.value = _.trophy;

JS引用TS的default导出

const { ccclass, property } = cc._decorator;
@ccclass
export default class BaseSwitchPanelEx extends cc.Component {
// ...
}

js应用ts,不考虑路径

let BaseSwitchPanelEx = require('BaseSwitchPanelEx').default;

JS引用TS的非default导出

export {
    // ...
    CCBindButton, CCBindAnimation, CCBindAnimationSimple, 
    // ...
};

js引用ts,不考虑路径

let CCBindButton = require('RxTools').CCBindButton;

或者可以这样写,以便于直接引用到其中的多个(这似乎叫做析构语法):

let { CCBindButton, CCBindAnimation } = require('RxTools');

JS引用TS,通过import语法

这部分我不是很了解

需要利用npm,先安装了@types。然后js代码里面就可以如同ts代码里面写如:

import Dialog from './Dialog';

其中Dialog是个同级目录下的ts文件。这里是用default导出的。

TS引用JS

直接require即可,就如同JS一样,同样不需要考虑路径

const i18n = require('LanguageData');

TS利用类型的引用结构分拆代码

这部分跟混编无关,暂时不知道JS里面如何去写

为了引用图集资源SpriteFrame:

const { ccclass, property } = cc._decorator;

@ccclass('SpriteFramesManagerResource')
export default class SpriteFramesManagerResource {
    @property(cc.SpriteFrame)
    coin: cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    diamond: cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    powerCoin: cc.SpriteFrame = null;
}

如果这个类继承cc.Component,那么直接在编辑器中指定引用即可。但是我有很多引用,希望归类。就写一个总的cc.Component,引用到这些子类。

import { BaseView } from "../../Rx/BaseView";
import SpriteFramesManagerResource from "./SpriteFramesManagerResource";
// ... 其它的分类导入
const { ccclass, property } = cc._decorator;

@ccclass
export default class BasicAssetsRefManager extends BaseView {

    private static _instance: BasicAssetsRefManager = null;

    public static getInstance(): BasicAssetsRefManager {
        return this._instance;
    }

    constructor() {
        super();
        BasicAssetsRefManager._instance = this;
    }

    @property(SpriteFramesManagerResource)
    resource: SpriteFramesManagerResource = new SpriteFramesManagerResource();
	
	// ... 其它的分类
}

在编辑器上,也会自动分类折叠这些自类引用。

最后

  1. 对于一些暂时没办法的红线提示 就使用: //@ts-ignore来规避吧。
  2. 要意识到,原JS里面的东西,进TS里面都是any。需要的话,使用<>给出定义。
  3. import需要考虑路径,require都不用。
  4. 考虑路径的引用,如果需要移动位置。在vscode里面可以自动修改引用目录关联(但是要注意meta文件可能变化导致引用丢失)
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值