Node.js + TypeScript 寫後端工具

浮生若夢的程式設計發表於2018-02-23

前言

現在 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 如下幾件事情:

  1. 專案的根目錄在哪? (以 tsconfig.json 所在的目錄為根目錄,即專案根目錄 )
  2. 輸入在哪? (即:專案的哪些ts 檔案是需要關心的,標準庫/第三方庫去哪裡找)
  3. 輸出在哪?(由於不是前端專案,所以我們只需要每一個 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 也不過是分分鐘的事情,並沒有什麼難度。

相關文章