詳解如何用typescript開(kāi)發(fā)koa2的二三事
前言
最近在寫(xiě)一個(gè)博客的項(xiàng)目,前端用的 vue+typescript+element-ui ,后臺(tái)則選擇了 koa2+typescript+mongoDB 的組合。寫(xiě)這篇博客的目的也是在寫(xiě)后臺(tái)的過(guò)程遇到一些問(wèn)題,查了很多資料才解決。于是權(quán)當(dāng)總結(jié),亦是記錄,可以給別人做一個(gè)完整的參考。
基本信息
這里列出來(lái)的是會(huì)用到的一些配置信息,畢竟一直都在更新,可能這里說(shuō)的以后某個(gè)版本就不支持了。
"nodemon" : "^1.18.3", "ts-node" : "^7.0.1", "typescript" : "^3.1.1" "node" : "9.0.0"
問(wèn)題描述
這次遇到的問(wèn)題其實(shí)都和typescript有關(guān)。koa2已經(jīng)出來(lái)很久了,開(kāi)發(fā)基本成熟,但是這次找資料的時(shí)候鮮有發(fā)現(xiàn)使用typescript開(kāi)發(fā)的,即便有,也都很簡(jiǎn)單,而且沒(méi)法解決我的問(wèn)題。
那言歸正傳,使用ts開(kāi)發(fā)koa,因?yàn)椴簧婕皐ebpack打包編譯,所以就會(huì)遇到幾個(gè)問(wèn)題:
- 編譯
- 實(shí)時(shí)刷新,重啟服務(wù)器
- debugger
這些確實(shí)是初期很困擾我的地方,使用node開(kāi)發(fā),最簡(jiǎn)單的無(wú)非是 node xxx.js ,進(jìn)一步也就是熱更新。但引入ts后就需要考慮編譯和實(shí)時(shí)刷新的問(wèn)題。畢竟不像每改一點(diǎn)代碼,就手動(dòng)重啟服務(wù)器,手動(dòng)編譯。
解決方案
以下是我的解決方案,后面我會(huì)說(shuō)一下為什么這樣寫(xiě),如果來(lái)不及看或者只想要答案的話(huà)復(fù)制就行。
"watch" : "ts-node ./app/index.ts", "start" : "nodemon --watch app/index.js", "build" : "tsc", "debugger" : "nodemon --watch ./app -e ts,tsx --exec node --inspect -r ts-node/register ./app/index.ts", "watch-serve": "nodemon --watch './app/**/*' -e ts,tsx --exec ts-node ./app/index.ts"
那我們一個(gè)一個(gè)來(lái)說(shuō)。
npm run watch

這個(gè)命令就是在本地使用 ts-node 啟動(dòng)一個(gè)服務(wù)器。來(lái)看一下對(duì) ts-node 的描述。
TypeScript execution and REPL for node.js, with source map support. Works with typescript@>=2.0.
這是一個(gè)在 node.js 的執(zhí)行和交互的typescript環(huán)境,簡(jiǎn)而言之就是為了ts而生的?。?/p>
那這條命令就是根據(jù)當(dāng)前的入口運(yùn)行程序,唯一的一個(gè)問(wèn)題是,不支持熱更新。所以pass。
npm run build && npm run start
這倆放一起說(shuō)是因?yàn)橄嚓P(guān)性比較高??梢哉f(shuō)是相互依賴(lài)的關(guān)系吧。
先說(shuō)第一條命令,很簡(jiǎn)單,就是編譯當(dāng)前的ts項(xiàng)目文件,輸出目錄需要在 tsconfig.json 中配置。我給大家看下我的運(yùn)行結(jié)果。

app 是我的項(xiàng)目文件,運(yùn)行命令后,會(huì)在根目錄下創(chuàng)建 dist 文件夾存放我編譯好的js文件,打開(kāi)就是這樣。

現(xiàn)在再說(shuō)第二條命令,就是根據(jù)編譯好的文件入口啟動(dòng)服務(wù)器。并且支持熱更新,但是, 注意這里有個(gè)但是 ,它只支持編譯過(guò)后的文件的熱更新,其實(shí)就是用js開(kāi)發(fā)koa的啟動(dòng)命令,那這時(shí)候在源文件中的任何修改都不會(huì)有作用,所以pass。
npm run watch-serve
重點(diǎn)來(lái)了,這才是解決問(wèn)題的關(guān)鍵?。。?/p>

這里完美的解決了 代碼的熱更新,實(shí)時(shí)編譯,服務(wù)器重啟 等問(wèn)題。很好的提升了開(kāi)發(fā)體驗(yàn)。
這個(gè)解決方案有一些中文博客提到,但是當(dāng)初用的時(shí)候不知道為啥這樣用,導(dǎo)致后期犯了一些現(xiàn)在看來(lái)很低級(jí)的錯(cuò)誤,這個(gè)就不提了。不過(guò)確實(shí)沒(méi)人說(shuō)明這段命令的意思,直到昨天碰到一個(gè)問(wèn)題,我才好好正視這個(gè)惡魔。
nodemon 和 ts-node 前文都介紹過(guò)了,我在這里只會(huì)針對(duì)具體的配置解釋一下。原本我的理解是這里用逗號(hào)分隔了兩個(gè)不同的命令,但是我太天真了。來(lái)看一下文檔的介紹。
By default, nodemon looks for files with the .js, .mjs, .coffee, .litcoffee, and .json extensions. If you use the --exec option and monitorapp.py nodemon will monitor files with the extension of .py. However, you can specify your own list with the -e (or --ext) switch like so:
nodemon -e js,jade
Now nodemon will restart on any changes to files in the directory (or subdirectories) with the extensions .js, .jade.
nodemon 有默認(rèn)吃的幾種文件類(lèi)型,分別是 .js, .mjs, .coffee, .litcoffee, and .json ,而我這里用的 .ts ,并不在默認(rèn)支持文件里,因此這里使用 -e 來(lái)指定我需要擴(kuò)展的文件類(lèi)型,這里的逗號(hào)也不過(guò)是用來(lái)分隔不同類(lèi)型用的。那這里提到了 --exec 這個(gè)配置。原文里說(shuō)如果用 nodemon 啟動(dòng) app.py 這個(gè)文件,那么將默認(rèn)支持 .py 這種擴(kuò)展類(lèi)型。另外文檔里還寫(xiě)了別的。
nodemon can also be used to execute and monitor other programs. nodemon will read the file extension of the script being run and monitor that extension instead of .js if there's no nodemon.json:
nodemon --exec "python -v" ./app.py
Now nodemon will runapp.py with python in verbose mode (note that if you're not passing args to the exec program, you don't need the quotes), and look for new or modified files with the .py extension.
這里說(shuō)明,除了默認(rèn)支持的擴(kuò)展,通過(guò)這個(gè)配置,可以支持和正在運(yùn)行的腳本一樣的擴(kuò)展。并且,如果擴(kuò)展程序不需要傳參數(shù)的話(huà),可以不寫(xiě)單引號(hào)。
綜上所述,一個(gè)命令用于增加支持的文件類(lèi)型,一個(gè)配置用來(lái)執(zhí)行和監(jiān)視其他類(lèi)型的程序。
至于 ---watch 這個(gè)參數(shù)。
By default nodemon monitors the current working directory. If you want to take control of that option, use the --watch option to add specific paths:
nodemon --watch app --watch libs app/server.js
Now nodemon will only restart if there are changes in the ./app or ./libs directory. By default nodemon will traverse sub-directories, so there's no need in explicitly including sub-directories.
Don't use unix globbing to pass multiple directories, e.g --watch ./lib/*, it won't work. You need a --watch flag per directory watched.
這里面需要注意的有兩點(diǎn),一是 nodemon 會(huì)默認(rèn)監(jiān)視當(dāng)前腳本文件執(zhí)行的文件夾,另一個(gè)就是如果要指定具體的文件夾時(shí),需要些詳細(xì)的路徑,比如絕對(duì)路徑或者相對(duì)路徑,絕對(duì)不要使用 通配符 。因此我命令行中的使用是無(wú)效且違反規(guī)則的,然而非要這樣寫(xiě)也不影響運(yùn)行。
原本到這也就結(jié)束了,然而昨天用了一個(gè)npm包,我想看看怎么運(yùn)行的,于是遇到了 debugger 的問(wèn)題,這也是迫使我去認(rèn)真弄懂這段命令的原因。
npm run debugger
基本的調(diào)試方式網(wǎng)上到處都有,我就不說(shuō)了,問(wèn)題還是導(dǎo)入typescript之后,讓一切都混亂起來(lái)。我最開(kāi)始嘗試了以下幾種命令:
'nodemon --inspect --watch ./app -e ts,tsx --exec ts-node ./app/index.ts' 'nodemon --watch --inspect ./app -e ts,tsx --exec ts-node ./app/index.ts' 'nodemon --watch ./app -e ts,tsx --exec ts-node --inspect ./app/index.ts'
這些都可以自己試著運(yùn)行一下,反正也沒(méi)啥用。然后就是今天一直想著這件事,換了幾個(gè)關(guān)鍵字google,找到這兩個(gè)地方。
https://github.com/TypeStrong/ts-node/issues/537
感謝stackoverflow和github,相互印證著看好像就明白是怎么回事了。
這里說(shuō)下 -r 這個(gè)參數(shù):

這里用于預(yù)加載一個(gè)模塊,并且可以多次使用這個(gè)參數(shù),那說(shuō)回我寫(xiě)的命令里, ts-node/register 就是一個(gè)模塊,或者不嚴(yán)謹(jǐn)?shù)恼f(shuō), register 是 ts-node 下的一個(gè)方法。這里就是使用node預(yù)加載ts-node的register模塊用來(lái)運(yùn)行ts程序,并且開(kāi)啟debugger模式。
后語(yǔ)
至此為止,在編譯,熱更新,debugger方面的坑應(yīng)該是踩完了,希望后面的人看了我寫(xiě)的文章能少走些彎路吧。也希望大家多多支持腳本之家。
- Typescript的三種運(yùn)行方式(小結(jié))
- JavaScript和TypeScript中的void的具體使用
- 教你30秒發(fā)布一個(gè)TypeScript包到NPM的方法步驟
- typescript nodejs 依賴(lài)注入實(shí)現(xiàn)方法代碼詳解
- 對(duì)TypeScript庫(kù)進(jìn)行單元測(cè)試的方法
- vue + typescript + 極驗(yàn)登錄驗(yàn)證的實(shí)現(xiàn)方法
- Typescript 中的 interface 和 type 到底有什么區(qū)別詳解
- Vue框架TypeScript裝飾器使用指南小結(jié)
- TypeScript基礎(chǔ)入門(mén)教程之三重斜線指令詳解
- 詳解TypeScript映射類(lèi)型和更好的字面量類(lèi)型推斷
相關(guān)文章
Node.JS更改Windows注冊(cè)表Regedit的方法小結(jié)
注冊(cè)表是windows操作系統(tǒng)中的一個(gè)核心數(shù)據(jù)庫(kù),這里介紹一些通過(guò)node.js操作注冊(cè)表的幾種方法,感興趣的朋友參考下吧2017-08-08
nodejs實(shí)現(xiàn)超簡(jiǎn)單生成二維碼的方法
這篇文章主要介紹了nodejs實(shí)現(xiàn)超簡(jiǎn)單生成二維碼的方法,結(jié)合實(shí)例形式分析了nodejs基于qr-image插件生成二維碼的相關(guān)操作技巧,需要的朋友可以參考下2018-03-03
淺析Node.js實(shí)現(xiàn)HTTP文件下載
本文介紹如何用Node.js來(lái)實(shí)現(xiàn)HTTP文件下載,文章以實(shí)例演示所以很詳細(xì),有需要的小伙伴們可以參考學(xué)習(xí)。2016-08-08
NodeJS實(shí)現(xiàn)不可逆加密與密碼密文保存的方法
這篇文章主要介紹了NodeJS實(shí)現(xiàn)不可逆加密與密碼密文保存的方法,簡(jiǎn)單講述了不可逆加密與密碼密文保存的原理并結(jié)合實(shí)例形式分析了nodejs相關(guān)加密操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-03-03
探索node之事件循環(huán)的實(shí)現(xiàn)
這篇文章主要介紹了探索node之事件循環(huán)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
NodeJS配置CORS實(shí)現(xiàn)過(guò)程詳解
這篇文章主要介紹了NodeJS配置CORS實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
node.js中的fs.writeSync方法使用說(shuō)明
這篇文章主要介紹了node.js中的fs.writeSync方法使用說(shuō)明,本文介紹了fs.writeSync的方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12
Node.js系列之發(fā)起get/post請(qǐng)求(2)
這篇文章主要為大家詳細(xì)介紹了Node.js系列之發(fā)起get/post請(qǐng)求,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08

