全部的入門教程幾乎都從「Hello World」講起,這個也不例外。html
接上文,咱們的項目目前仍是個空殼子,什麼都沒有,如今要先進行項目初始化操做。node
View
-Integrated Terminal
來打開內置的Terminalnpm init
命令來建立package.json文件,許可證那我該成了MIT,其它基本都是默認,直接回車便可安裝koa及對應的types,這裏建議再安裝一遍typescript,這樣能夠保持其版本跟着這個項目走,而不是全局webpack
npm install koa --save npm install @types/koa --save-dev npm install typescript --save-dev
執行完上述命令後根目錄下會新增package-lock.json文件,這個文件是隻有npm v5.0以上版本纔會生成的,其與yarn工具生成yarn.lock文件相似,主要是用來記錄已安裝模塊的整個依賴關係,下次install時直接根據該文件去獲取依賴庫,具體狀況能夠看官方文檔:https://docs.npmjs.com/files/...--save
選項指將其該依賴保存至package.json中的dependencies
下,若是後面有-dev
,則保存至devDependencies
下git
安裝好一些基礎依賴庫以後,咱們須要配置一下tsconfig,這個配置文件用於typescript將/.tsx?/
文件編譯成js,裏面有不少配置項,具體能夠查看這個中文文檔:https://tslang.cn/docs/handbo...
在根目錄
下面新建一個tsconfig.json
文件es6
// ./tsconfig.json { "compilerOptions": { "outDir": "./dist/", "target": "es5" } }
最簡單的配置就是上面這樣,設定好要編譯後的js版本(target
),和編譯後js要輸出到的所在目錄(outDir
)。github
PS:爲啥要用typescript,由於ts是es的超集,還有類型檢查,另外再也不須要babel,簡單來講,babel有的ts都有,babel沒有的ts也有
web
咱們在服務端目錄下新建index.ts做爲服務端入口,另外新建一個config.ts做爲服務端配置項文件。typescript
// ./src/server/config.ts export default { port: 3344, };
// ./src/server/index.ts import * as Koa from 'koa'; import serverConfig from './config'; const app = new Koa(); const { port } = serverConfig; app.use((ctx: Koa.Context, next) => { ctx.body = 'hello world'; next(); }); app.listen(port, () => { console.log(`Koa app started at port ${port}`); });
疑問一:爲什麼要import * as Koa from 'koa';而不是import Koa from 'koa';?
答:這個問題涉及到import語句的基本語法(見MDN import),不少同窗在配合babel的時候都習慣於使用後者這種方式。前者導入全部內容,後者導入默認值。查看koa的源碼可見其使用module.exports來設置要導出的內容,根據上述tsconfig中target爲es5,此時ts會使用對於es5的默認模塊規範即commonjs來處理這些導入導出的模塊,而koa源碼中並無設置導出的默認值,即default值,因此須要使用前者這種寫法,而babel會作額外的處理(見exporting 'exports.default' rather than 'exports'),使得可使用後者這種寫法。npm
疑問二:我就想在ts裏使用import Koa from 'koa';這種寫法,該怎麼辦?
答:在tsconfig.json中添加以下屬性:json
// ./tsconfig.json { ... "compilerOptions": { ... "allowSyntheticDefaultImports": true, // 容許從沒有設置默認導出的模塊中默認導入。這並不影響代碼的顯示,僅爲了類型檢查。 ... } ... }
疑問三:爲什麼不直接import { port } from './config';而要寫兩行代碼?
答:import語句中的{ a }
,和es6中const { b } = xxx;
並非同一回事,前者是導入模塊的單個成員a,後者是解構xxx對象的屬性b,而port根本不是config導出的模塊成員之一,config只導出了一個模塊成員即default。
疑問四:Koa.Context是什麼東西?「ctx: Koa.Context」又是什麼語法?
答:ts中對於變量可以使用:
對其進行類型聲明,這裏的Koa.Context即ctx上下文的類型。
咱們將鼠標移上去能夠看到簡要信息,點擊能夠跳轉到詳細的類型聲明文件中看到具體的定義。
咱們使用tsc命令來編譯ts文件,爲了方便調用,我將編譯命令寫入了package.json文件中的scripts屬性下。
// ./package.json { ... "scripts": { ... "tsc": "tsc -w -p tsconfig.json", ... }, ... }
執行如下命令:
npm run tsc
能夠看到控制檯出現上述信息,且不能再進行輸入命令了,另外咱們在根目錄下發現多出一個dist
目錄,裏面有兩個文件,config.js和index.js。
疑問五:爲何生成的文件不是在./dist/server目錄下,而是直接在./dist下了?
答:這個能夠說(我猜想,可能有配置方法,但目前我沒找到)是一個bug,主要表現就是被編譯的ts文件都處於一個目錄下,那麼生成的js文件都會直接被導出到dist目錄下,爲了不此問題,咱們在./src/client目錄下新建一個空的index.ts文件,重寫執行編譯命令便可生成正確目錄下的文件了。
咱們使用node來啓動咱們的koa app,一樣我將該命令放在了package.json文件中。
// ./package.json { ... "scripts": { ... "dev": "node ./dist/server/index.js", ... }, ... }
執行如下命令:
npm run dev
打開瀏覽器,訪問如下地址:
http://localhost:3344
可見hello world出現。
疑問六:怎麼再開一個vs code裏的terminal?
答:以下圖,在原terminal窗口右上角按小加號便可
By devlee