前言
現在 Node.js 的生態越來越成熟,有好多公司直接使用 Node 構建其後端應用,放線上上跑。TypeScript 是微軟的程式語言,近年來受到的關注也是越來越多。
作為一個常年寫後端介面的人,便想:能不能利用這兩者,來給自己的工作流,帶來一點不一樣的感覺。(由於這不是寫客戶端 JS,所以我們並不需要 webpack 等工具 )
步驟
初始化專案
假設專案目錄是 project 。
cd project
mkdir src && touch README.md
cd src
npm init
tsc --init
根據慣例,弄一個主入口 main (注:這裡沒有使用 index.js 這種設定 )
touch main.ts
複製程式碼
初始化完成的專案是這樣的:
project/
README.md
src/
package.json
tsconfig.json
main.ts
複製程式碼
安裝必備的包
目前暫時只想到瞭如下的這些包:
npm install --save lodash @types/lodash
npm install --save @types/node
npm install --save-dev typescript
複製程式碼
之後專案變成這樣子:
project/
README.md
src/
package.json
tsconfig.json
main.ts
node_modules/
複製程式碼
配置 tsconfig.json
這一步最為重要。官網有一節專門講這個:http://www.typescriptlang.org/docs/handbook/tsconfig-json.html 。要看懂還是需要花點時間的。
總而言之,需要告訴 tsc 如下幾件事情:
- 專案的根目錄在哪? (以 tsconfig.json 所在的目錄為根目錄,即專案根目錄 )
- 輸入在哪? (即:專案的哪些ts 檔案是需要關心的,標準庫/第三方庫去哪裡找)
- 輸出在哪?(由於不是前端專案,所以我們只需要每一個 ts 輸出對應的 js 檔案即可)
這裡是一個示例配置,有詳細的註釋說明,初始化 ts 專案時,可以直接拷貝之,以節約時間成本。
{
// tsconfig 所在的根目錄, 則是一個project
"compilerOptions": {
"module": "commonjs", // 模組系統
"target": "es2015", // 生成目標, 一般選擇ES6,因為不是客戶端環境,沒必要還編譯成 ES5
// 一組嚴苛的編譯選項
"noImplicitAny": false,
"strictNullChecks": true,
"strict": true,
"alwaysStrict": true,
"sourceMap": false,
"noImplicitReturns": true,
"noImplicitThis": true,
"pretty": true,
"listFiles": true, // 包含了哪些庫,這個必要的時候還是很有用的
"listEmittedFiles": true,
"lib": [ // 要那些 lib,按需選擇即可
"es2016"
],
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "noFallthroughCasesInSwitch": true,
// 指定庫的搜尋路徑,這個比較有用,一般會指定 @types,還可以按需新增
"typeRoots": [
"./node_modules/@types"
]
// 庫搜尋路徑下, 僅使用哪些庫, 一般沒啥用
// "types": [
// ]
},
// file include會算出一個交集, 指明哪些是專案的 ts 檔案
"include": [
"./**/*"
],
// 排除專案下面不符合要求的檔案,這個按需設定即可,可以放心排除亂七八糟的檔案
"exclude": [
"node_modules",
"**/*.spec.ts",
"*.js"
]
}
複製程式碼
設計專案的目錄結構 為了模擬真實的場景,我們的 main.ts 有如下內容:
function main() {
}
main();
複製程式碼
寫一個 utils.ts,放入 src/core/utils.ts 中。
import * as path from 'path'; // 測試能否正常使用 Node 的內建模組
/**
* 一個正常的class
*
* 不得不說, TS 使用起來真是舒服,各種該有的東西都替你考慮到了
* 很舒心
*/
export class NodeModuleTester {
public static readonly STATIC_VAR = 'STATIC'; // 測試static變數
constructor( // 測試構造方法
private readonly f1: string,
private readonly f2: number) {
}
public static testPath() { // 測試靜態方法
const curdir = './';
console.log(path.resolve(curdir));
}
}
複製程式碼
由於需要使用對應的 class,所以 main.ts 內容變成了這樣:
import {NodeModuleTester} from './core/utils';
/**
* main 入口
*
* 測試!
*/
function main() {
const tester = new NodeModuleTester("s1", 1);
console.log(NodeModuleTester.STATIC_VAR);
console.log(NodeModuleTester.testPath());
}
main();
複製程式碼
執行 由於 Node 是不認識 ts 的,我們的 ts 程式碼需要先轉譯成 js 程式碼。
不過別擔心,我們使用的是微軟的產品,一切都不是問題(意思就是:微軟設計的東西,既有品味,又是異常簡單好用,歷來如此)。
我們只需要 cd src/ && tsc && node main.js
即可,簡直不要太簡單。如果還嫌麻煩,我們可以寫到 npm script 中去,如下:
{
"name": "src",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"runmain": "./node_modules/.bin/tsc && node main.js" // 就是這個指令碼!
},
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^9.4.6",
"typescript": "^2.7.2"
}
}
複製程式碼
然後我們只需要cd src/ && npm run runmain
即可,更加地簡單。
我的感悟
TypeScript 程式碼,既美觀又優雅,加上微軟強大的工程能力(造工具的能力),Node.js + TypeScript 幾乎是一對完美的組合。
附
- 有人可能比較擔憂有的庫沒有對應 d.ts 。其實這完全不用擔心,常用的庫要麼自帶 d.ts (側面驗證了 TS已經越來越被大家接受),要麼社群已經有維護好的 d.ts (@types下面的庫),實在沒辦法,自己寫 d.ts 也不過是分分鐘的事情,並沒有什麼難度。