
!??!不推薦警告?。。?/strong>
如果你是第一次打開(kāi)這篇文章的話,我推薦使用 Screeps 使用 TypeScript 進(jìn)行靜態(tài)類(lèi)型檢查 的方法來(lái)搭建你的 ts screeps 開(kāi)發(fā)環(huán)境,這篇內(nèi)容包含了更完善的構(gòu)建流程,并介紹了在搭建過(guò)程中可能會(huì)遇到的一些問(wèn)題。本篇內(nèi)容雖然還可以使用,但是已經(jīng)過(guò)時(shí)并不在維護(hù)。
開(kāi)始構(gòu)建 TS 項(xiàng)目!
接下來(lái)我們就從零開(kāi)始,搭建一個(gè)用于 screeps 的 ts 項(xiàng)目。注意,下面的內(nèi)容對(duì)于沒(méi)有 ts 基礎(chǔ)的同學(xué)可能有些難以理解,我會(huì)盡量對(duì)出現(xiàn)的名詞進(jìn)行解釋。
1> 基本項(xiàng)目搭建
首先我們找個(gè)安靜祥和的地方新建個(gè)名為ts-screeps的文件夾,或者其他你喜歡的名字,沒(méi)影響。然后切換到文件夾內(nèi)執(zhí)行如下命令來(lái)進(jìn)行基本的依賴安裝,如果你安裝很慢的話請(qǐng)自行百度"npm 切換國(guó)內(nèi)源":
// 初始化項(xiàng)目
npm init // 然后一路回車(chē)
// 安裝項(xiàng)目依賴
npm install @types/lodash@3.10.1 @types/screeps @types/node grunt typescript grunt-ts
// 全局安裝 grunt 命令行,如果之前安過(guò)可以跳過(guò)
npm install grunt-cli -g
先來(lái)簡(jiǎn)單介紹一下我們安裝的依賴
-
@types/screepsscreeps 游戲的聲明文件, 注意,這個(gè)依賴并不是游戲本體,而僅僅是對(duì)游戲 api 的描述文件,下面lodash相同。 -
@types/lodash@3.10.1lodash 的聲明文件 -
@types/nodenode.js 的聲明文件 -
grunt自動(dòng)化腳本 -
typescriptts 編譯器本體 -
grunt-ts使用 grunt 進(jìn)行 ts 自動(dòng)編譯的任務(wù) -
grunt-cli可以使用grunt命令
這里多解釋下上面安裝的幾個(gè)@types聲明文件,由于 ts 帶有靜態(tài)類(lèi)型檢查,而如何讓 ts 編譯器知道我們使用的第三方包的類(lèi)型呢?就是通過(guò)安裝這些@types聲明文件。并且如果你使用同樣由 ts 開(kāi)發(fā)的VScode進(jìn)行代碼編寫(xiě)時(shí),VScode還能自動(dòng)根據(jù)這些安裝的聲明文件為你 提供代碼補(bǔ)全。
安裝完成之后我們的項(xiàng)目目錄是這樣的:

2> 創(chuàng)建 Grunfile 自動(dòng)化腳本
接下來(lái)我們配置 ts 編譯任務(wù),在和package.json同級(jí)的目錄下新建Gruntfile.js文件,并填入如下內(nèi)容:
module.exports = function(grunt) {
// 從 npm 載入任務(wù)
grunt.loadNpmTasks("grunt-ts")
// 配置任務(wù)
grunt.initConfig({
// typescripts 編譯任務(wù)
'ts': {
default : {
options: {
sourceMap: false,
// 編譯到的目標(biāo)版本
target: 'es5',
rootDir: "src/"
},
// 要進(jìn)行編譯的目錄及文件
src: ["src/*.ts"],
// 編譯好的文件的輸出目錄
outDir: 'dist/'
}
}
})
// 將 ts 編譯任務(wù)注冊(cè)到默認(rèn)執(zhí)行命令
grunt.registerTask('default', [ 'ts' ])
}
簡(jiǎn)單介紹一下,Gruntfile是定義本項(xiàng)目中的自動(dòng)化腳本如何執(zhí)行。里邊分為三部分:
- 載入 ts 編譯任務(wù)
grunt.loadNpmTasks - 配置 ts 編譯任務(wù)
grunt.initConfig - 將編譯任務(wù)注冊(cè)到默認(rèn)命令
grunt.registerTask
怎么執(zhí)行任務(wù)我們一會(huì)再講,我們先來(lái)新建源代碼的存放目錄。
3> 新建代碼存放目錄
在項(xiàng)目目錄下新建名為src的文件夾,我們的 ts 源文件都要放到這里。如果不想叫這個(gè)名字的話請(qǐng)同步修改Gruntfile.js里 ts 編譯任務(wù)中的rootDir和src屬性。
新建完文件夾后我們寫(xiě)一個(gè)最基本的 ts screeps 入口文件main.ts:
// screeps 代碼入口
module.exports.loop = function(): void {
console.log(sayHello('world!'))
}
// 定義一個(gè) ts 風(fēng)格的方法
function sayHello(str: string): string {
return 'hello' + str
}
可以看到,代碼中定義的函數(shù)通過(guò):字符指定了參數(shù)和返回值的類(lèi)型,想簡(jiǎn)單了解一下 ts 的語(yǔ)法可以參考 《ts 官方文檔 - 五分鐘上手》。
到目前為止,我們的項(xiàng)目目錄就變成了這個(gè)樣子:

ok, 完事具備,接下來(lái)我們就可以動(dòng)手編譯了!
4> 編譯項(xiàng)目!
我們?cè)陧?xiàng)目根目錄下打開(kāi)控制臺(tái),執(zhí)行如下命令,就可以看到編譯任務(wù)開(kāi)始執(zhí)行了:
grunt
等待幾秒鐘之后,就可以看到編譯完成了,控制臺(tái)輸出如下:
Running "ts:default" (ts) task
Compiling...
Using tsc v3.6.3
TypeScript compilation complete: 3.57s for 1 TypeScript files.
Done.
這時(shí)候我們就可以看到項(xiàng)目根目錄下自動(dòng)生成了一個(gè)名為dist的文件夾,里面就是編譯好的文件:
main.js
module.exports.loop = function () {
console.log(sayHello('world!'));
};
function sayHello(str) {
return 'hello' + str;
}
可以看到 ts 把我們的源碼中的類(lèi)型定義剔除了并轉(zhuǎn)換到了我們指定的es5版本(這個(gè)轉(zhuǎn)換不太看得出來(lái),不過(guò)了解就好 )。接下來(lái),我們只需要通過(guò)grunt-screeps或者grunt-contrib-copy任務(wù)將其提交到游戲服務(wù)器即可。至于提交如何實(shí)現(xiàn)請(qǐng)查看 screeps 配置無(wú)需游戲客戶端的開(kāi)發(fā)環(huán)境,文中還介紹了如何在文件保存時(shí)自動(dòng)進(jìn)行編譯。
優(yōu)化異常追蹤棧
由于 ts 會(huì)將所有代碼都打包進(jìn)一個(gè)文件,所以 當(dāng)你的代碼報(bào)錯(cuò)后顯示的異常調(diào)用棧實(shí)際上是編譯后的 main.js 中的位置,而不是你源代碼中的實(shí)際報(bào)錯(cuò)位置。這也就導(dǎo)致了報(bào)錯(cuò)后需要對(duì)照著編譯后的代碼去確定到底是那里出現(xiàn)了問(wèn)題,當(dāng)你的代碼增多到幾千行后這個(gè)體驗(yàn)會(huì)非常糟糕,那么能不能解決這個(gè)問(wèn)題呢?
是的你可以,通過(guò)一些配置手段和額外代碼,你可以讓錯(cuò)誤堆棧追蹤你源代碼的信息而不是編譯后的代碼。但是,想這么做依舊有一定的難度,并且會(huì)不可避免的消耗你那么一丟丟的 cpu。所以為了簡(jiǎn)單起見(jiàn),本文不會(huì)加入調(diào)試優(yōu)化的內(nèi)容。
如果你確實(shí)有興趣的話。你可以按照下面兩個(gè)鏈接來(lái)升級(jí)你的項(xiàng)目:
總結(jié)
本文介紹了如何在 screeps 游戲項(xiàng)目中使用 ts 進(jìn)行開(kāi)發(fā),通過(guò)grunt執(zhí)行grunt-ts任務(wù)將我們的 ts 源碼編譯成原生的 js 文件。然后就可以將編譯好的文件提交到游戲服務(wù)器。
除此之外,github 上還有人開(kāi)源了如何在 screeps 中使用 ts 的模板項(xiàng)目 screeps-typescript-starter 有興趣也可以嘗試下。
如果你在使用的時(shí)候遇到了什么疑問(wèn)的話,歡迎加群565401831提問(wèn)~