輕量版 NodeJS TypeScript Starter
2018-07-24
今天分享一下我的 TypeScript project 設定,當中包括了一些基本功能:
- Express Server + body parser
- TypeScript
- 比較寬鬆的 Tslint
- Nodemon 自動重啟伺服器
- Module Alias (方便
import
的工具) - Mocha Unit Test
- Production 和 Dev 的 Build Script
安裝和運行
先從 git 下載項目然後安裝模組
$ git clone https://github.com/auphone/node-typescript-starter.git
$ cd node-typescript-starter
$ npm install
打開兩個 terminal
或 cmd
或 shell
,執行以下語句
第一個 terminal
$ npm run watch-ts
另一個 terminal
$ npm serve
最後打開瀏覽器測試 API
全部指令
npm run watch-ts
- 監測並 compile
src
內的 TypeScript 原碼
npm run serve
- 執行 Nodemon,與
npm watch-ts
同時使用
npm start
- 直接運行
dist/
,需要先進行 Compile
npm run test
- 執行
src/**/*.spec.ts
目錄下的 Unit test
npm run build
- Dev 環境的 Build
npm run build-prod
- Production 環境的 Build
Tslint
這是我的 tslint.json
設定,我覺得用 tslint --init
產生出來的設定太嚴緊了,所以修改了一下
{
"rules": {
"class-name": true,
"comment-format": [true, "check-space"],
"indent": [true, "spaces"],
"one-line": [true, "check-open-brace", "check-whitespace"],
"no-var-keyword": true,
"quotemark": [true, "single", "avoid-escape"],
"semicolon": [true, "always", "ignore-bound-class-methods"],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-separator",
"check-type"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
],
"no-internal-module": true,
"no-trailing-whitespace": true,
"no-null-keyword": true,
"prefer-const": true,
"jsdoc-format": true
}
}
用 paths
方便指向目錄
在 TypeScript 設定 paths
可以解決 import
很多層目錄時產生出的 ../
,例如
import { app } from "../../../app";
這是我的 tsconfig.json
,因為我同時有開發 Angular 所以使用了相似的設定
{
"compilerOptions": {
...
"paths": {
"@app/*": ["*"],
"@env/*": ["environments/*"]
}
}
}
設定好了以後我們就可以在任何地方用 @app
指向根目錄了
// 以前
import * as someModule from "../../modules/someModule";
// 現在我們可以寫成這樣
import * as someModule from "@app/modules/someModule";
然後我還會在每層資料夾設定一個 index.ts
(barrel),再在裡面 export *
所有需要的模組
export * from "./server.model";
然後我們就可以這樣做
import * as fromModels from "@app/models/";
fromModels.doSomething();
Module Alias
雖然 TypeScript 有 paths
的功能,但是在 NodeJS 我們不會用 WebPack,所以在 compile 的時候還是要自行添加一些設定,這邊我就用了 module-alias 這個模組,為了方便在不同環境和 unit test 的時候使用,我還會把它分拆成一個獨立模組使 spec
也能夠使用,而設定就跟 TypeScript 的 paths
指向一樣的地方
import * as alias from "module-alias";
import * as path from "path";
export const init = () => {
alias.addAliases({
"@app": __dirname,
"@env": path.resolve(__dirname, "./environments"),
});
};
Unit Test
Unit Test 有幾種常用結構,我個人比較喜歡把 .spec
與模組放到同一個目錄亦即 src
內,也有人喜歡把它們全放在 test/
內,都是因人而異,mocha
和 chai
也是個人喜好而採用的
import { expect } from "chai";
import * as path from "path";
// Init Alias
import * as alias from "../alias";
alias.init();
import * as fromServer from "./server.model";
describe("GET Environment", () => {
it("should be equal to dev", () => {
return expect(fromServer.getEnv()).eq("dev");
});
});
Build
預設有兩個指令,Dev 伺服器的 npm run build
和 Production 伺服器的 npm run build-prod
,這邊只做了一個複製 environment.prod.ts
到 environment.ts
的動作
後記
由於我經常會做很多 POC,但 Typescript 不像 JS 一樣只要一個 .js
那麼簡單,所以建立一個 starter 的確讓我省了不少時間