白鷺引擎在2017年1月10日發(fā)布了 4.0 版本祈搜,將內(nèi)部編譯器提升到了 TypeScript 2.1 较店。 本文的主要目標(biāo)是向開發(fā)者介紹這為開發(fā)者帶來了哪些改變。
概述
在白鷺引擎 3.x 時(shí)代容燕,引擎在執(zhí)行構(gòu)建命令時(shí)泽西,使用的是內(nèi)部定制的 TypeScript 1.8 編譯器,“內(nèi)部定制” 主要包括:
- 添加生成類名稱注冊功能缰趋,以便白鷺引擎的反射 API
- 根據(jù)依賴關(guān)系,進(jìn)行自動(dòng)的文件排序功能
- 優(yōu)化一些底層輸出邏輯陕见,降低編譯體積
在白鷺引擎4.0版本秘血,我們將編譯器版本從 TypeScript 1.8 提升到了 TypeScript 2.1,您可以從 TypeScript 官方文檔 了解從 TypeScript 1.8 至 2.1 引入的全新特性评甜。除此之外灰粮,我向開發(fā)者簡單介紹一些常見的技巧和問題解決方式
新特性
允許使用 ECMAScript 6 的絕大部分新語法
您需要在tsconfig.json
中添加以下內(nèi)容
{
"compilerOptions": {
"target": "es5",
"lib":[
"es5","dom","es6"
]
}
}
當(dāng)您添加es6
字段后,就可以在白鷺引擎中使用全部 ES6 的新特性忍坷。ES6 功能列表您可以參見 ECMAScript 6 入門 這篇文章粘舟。
ECMAScript 6 的新特性中熔脂,屬于語法的部分會(huì)由 TypeScript 直接編譯為舊瀏覽器兼容的實(shí)現(xiàn)。屬于 API 的部分是需要開發(fā)者加入一個(gè) polyfill 以保證舊瀏覽器不會(huì)報(bào)錯(cuò)柑肴。目前引擎并沒有添加這些 polyfill霞揉,但是我們有計(jì)劃在 4.0.x 版本中為開發(fā)者自動(dòng)添加 polyfill 支持。
更智能晰骑、更嚴(yán)格的 TypeScript 類型推斷
白鷺引擎4.0 版本中我們針對(duì) TypeScript 的特性适秩,將引擎 API 進(jìn)行了更細(xì)致的梳理,引入更細(xì)致的 API 方法簽名硕舆,以比較常見的 DisplayObject.addEventListener
這個(gè) API 為例秽荞,原來的方法簽名為
class DisplayObject {
public addEventListener(type:string,listener:Function,thisObject:any) {
}
}
class Main {
private run() {
var button = new DisplayObject();
button.addEventListener(egret.TouchEvent.TOUCH_TAP,
function(e:egret.TouchEvent) { // 事件類型必須手動(dòng)聲明為 egret.TouchEvent,才能保證嚴(yán)格類型
this.doSomething(); // 第三個(gè)參數(shù)傳遞的是 button抚官,函數(shù)里的 this 應(yīng)該是button扬跋,不是 Main 的實(shí)例,所以不能調(diào)用 doSomething() 方法
},button);
);
}
private doSomething(){
}
}
比如在白鷺引擎4.0版本中凌节,DisplayObject 的類型被調(diào)整為了以下類型
class DisplayObject {
public addEventListener<Z>(type:"tap",listener:(this:Z,e:egret.TouchEvent),thisObject:Z)
public addEventListener<Z>(type:string,listener:(this:Z,e:egret.Event),thisObject:Z) {
}
}
class Main {
private run() {
var button = new DisplayObject();
button.addEventListener(egret.TouchEvent.TOUCH_TAP,
function(e) { // 事件類型無需手動(dòng)聲明就可保證嚴(yán)格類型
console.log (e.local_x) //由于已經(jīng)推斷出 e 的類型是 egret.TouchEvent钦听,所以這里會(huì)報(bào)錯(cuò)
this.doSomething(); //自動(dòng)推斷出這里的 this 應(yīng)該是 button,進(jìn)而檢查出這里會(huì)報(bào)錯(cuò)
},button);
);
}
private doSomething(){
}
}
允許使用 async / await 關(guān)鍵詞
async / await 是 ES2017 語法標(biāo)準(zhǔn)刊咳,他可以大幅節(jié)省異步代碼的處理彪见。注意使用這個(gè)語法糖需要在 tsconfig.json
中添加 lib : es6
或者 lib : es2015.promise
可能問題
升級(jí)到白鷺引擎4.0之后,您可能會(huì)遇到以下問題:
- Egret Wing 代碼提示報(bào)錯(cuò)娱挨。
如果您遇到這種問題是因?yàn)槟?IDE 尚不支持 TypeScript 2.1余指,請把對(duì)應(yīng)的 IDE 升級(jí)至最新版本。 Egret Wing 升級(jí)至 4.0 以上版本跷坝。 - 編譯代碼報(bào)錯(cuò)
升級(jí)到 TypeScript 2.1 之后酵镜,TypeScript 變得更為智能,也變得更為嚴(yán)格柴钻,可能會(huì)有一些之前的不規(guī)范的寫法會(huì)導(dǎo)致報(bào)錯(cuò)淮韭,對(duì)其進(jìn)行調(diào)整即可,比如if ( x == false ) {
這樣的邏輯在 TypeScript 1.8 不會(huì)報(bào)錯(cuò)贴届,但是在 2.1 會(huì)報(bào)錯(cuò)靠粪,因?yàn)檫@種代碼雖然是可以正確運(yùn)行,但是有很大的潛在風(fēng)險(xiǎn)(比如 x = 0 )的時(shí)候毫蚓。 - 編譯代碼出現(xiàn)錯(cuò)誤占键,典型錯(cuò)誤堆棧如下:
D:\GitHub\egret-core\tools\lib\typescript-plus\lib\typescript.js:57926
callExpression.arguments.forEach(function (argument) {
^
TypeError: Cannot read property 'forEach' of undefined
at visitCallExpression (D:\GitHub\egret-core\tools\lib\typescript-plus\lib\t
ypescript.js:57926:33)
at visitExpression (D:\GitHub\egret-core\tools\lib\typescript-plus\lib\types
cript.js:57824:17)
at visitStaticMember (D:\GitHub\egret-core\tools\lib\typescript-plus\lib\typ
escript.js:57765:17)
at visitStatement (D:\GitHub\egret-core\tools\lib\typescript-plus\lib\typesc
ript.js:57616:17)
at visitFile (D:\GitHub\egret-core\tools\lib\typescript-plus\lib\typescript.
js:57602:13)
at buildDependencyMap (D:\GitHub\egret-core\tools\lib\typescript-plus\lib\ty
pescript.js:57590:13)
at Object.reorderSourceFiles (D:\GitHub\egret-core\tools\lib\typescript-plus
\lib\typescript.js:57562:9)
at Compiler.sortFiles (D:\GitHub\egret-core\tools\actions\Compiler.js:113:29
)
at Compiler.compileNew (D:\GitHub\egret-core\tools\actions\Compiler.js:101:1
4)
at Compiler.compileGame (D:\GitHub\egret-core\tools\actions\Compiler.js:52:2
5)
這個(gè)問題是我們在進(jìn)行版本升級(jí)時(shí)考慮不周引發(fā)的問題,對(duì)此非常抱歉元潘,這個(gè)問題已經(jīng)在下一個(gè)版本( 4.0.1 ) 確認(rèn)會(huì)得到解決畔乙,您也可以通過盡可能的不要在類的靜態(tài)屬性中直接創(chuàng)建對(duì)象來規(guī)避這個(gè)問題。