如何開始在 nodejs 使用 typescript ?
結論:
安裝:
- typescript, 當然就是 TypeScript.
- typings, TypeScript Definition Manager. 要用到其他第三方函式庫, 就必須要型別定義檔, 自己編寫也行, 但最好還是有管理他們的工具.
> npm install -g typescript typings
> tsc -v
//Version 1.8.10
轉譯:
- 簡單使用
tsc
.
- 或建立 TypeScript 的專案檔 ‘tsconfig.json’, 使用
tsc -p
,
為專案檔所在目錄.
引用:
- 使用
typings
安裝第三方函式庫的 TypeScript definitions.
- 修改 ‘tsconfig.json’, 將定義檔 “typings/index.d.ts” 加入 “files” 或 “filesGlob”.
> npm install --save
> typings install --save
// 在新版的 TypeScript 2.0 你可以用下面的命令代替 `typings install `
> npm install --save @types/
// 你可以在[這裡](https://aka.ms/types) 查有哪些可以用
// 其實應該就是 `typings search --source npm` 的 Web 版
// 但可以省掉處理 `typings` 的 `.d.ts` 檔.
監控: 使用 tsc -w -p
來監控檔案, 在檔案有變動時進行轉譯.
> npm install -g typescript typings
> tsc -v
//Version 1.8.10
tsc
.tsc -p
,
為專案檔所在目錄.typings
安裝第三方函式庫的 TypeScript definitions.> npm install --save
> typings install --save
// 在新版的 TypeScript 2.0 你可以用下面的命令代替 `typings install `
> npm install --save @types/
// 你可以在[這裡](https://aka.ms/types) 查有哪些可以用
// 其實應該就是 `typings search --source npm` 的 Web 版
// 但可以省掉處理 `typings` 的 `.d.ts` 檔.
tsc -w -p
來監控檔案, 在檔案有變動時進行轉譯.廢話:
ES6 改名叫 ECMAScript 2015, 好長的名字. 我還是叫他 ES6 吧. 參考一下ES6 支援度, 目前(20160805)還沒有 100% 支援的環境, 雖然他叫 ECMAScript 2015. 想要好好寫 ES6, 還是得找個轉譯器, 但取名 babel 多不吉利阿.
TypeScript 雖然明明只是個 Script, 但卻是偶像(Anders Hejlsberg)操刀. 所以我偏心了. 我連 ES7 都不知道長甚麼樣子, TS 卻去支援 ES8 的特性, 天知道是甚麼鬼阿!
正文:
使用 npm
安裝完 typescript 與 typings 後, 開始寫第一個程式: hello.ts. 沒看錯附檔名要從熟悉的 .js
改為 .ts
. 就讓我們寫一個有 typescript
風格的程式碼吧, 如下
var hello = (word: string) => {
console.log(`Hello, ${word}`);
}
hello("TypeScript");
他會轉譯為,
> tsc hello.ts; cat hello.js
/**
var hello = function (word) {
console.log("Hello, " + word);
};
hello("TypeScript");
*/
跟一般一樣, 執行 node hello.js
即可.
但寫程式怎麼能不用第三方函式庫? 不管是 lodash
還是 async
, 沒有了, 可是會直接降低一階的生產力. 雖然 ES6 新增的 Generator 和部分方法可替代, 但畢竟是在過度期, 並不是全部的環境都支援, 熟悉與法也需要一段時間. 這時候就輪到 typings
出場. 安裝完 typings
後, 會多出一個叫 “typings”(類似 NPM 中 node_modules 的角色) 的目錄來放 TypeScript 的定義檔.
> typings init
// 會產生一個 typings.json (類似 NPM 中的 package.json)檔案.
> npm install lodash --save
// 安裝 lodash, 已經安裝了就可以略過
> typings install lodash --save
// 會將定義檔放到 "typings/modules/lodash/" 下
改寫一下 hello.ts, 如下 helloAnybody.ts
import * as _ from "lodash";
var hello = (compiler: string) => {
console.log(`Hello, ${compiler}`);
}
var anybody = ["TS","JS","Node"];
_(anybody).each(hello);
為了下指令方便起見, 讓我們編輯 TypeScript 的專案檔. 先利用 tsc --init
產出一個 “tsconfig.json”, 如下
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false
},
"exclude": [
"node_modules"
]
}
基本上 “tsconfig.json” 的檔案內容只要 {}
就可以了. 但如果是這樣所有的參數就會採內定值, 這可能不是我們要的. 其實如果是這樣有這個檔跟沒有是一樣的. 所以, 接下來就一些主要會用到的部分進行解釋與修改. “tsconfig.json” 主要有兩部分,
- compilerOptions, 指示
tsc
應該將檔案轉譯成什麼樣的 JavaScript.
- exclude, files, 指示
tsc
要轉譯哪些檔案.
首先是 “compilerOptions” 的部分,
- target: 指示採用哪一版的JS. 可用的值有 “es3”, “es5”, “es6”, 內定是 “es5”. 基本上 “es5” 是一個合適的選擇, 除非你運行在一個特別舊的環境.
- module: 指示採用哪種模組模式, 可用的值有 “none”, “commonjs”, “amd”, “system”, “umd”, “es6” 或 “es201”. 但如果 “target” 在 “es5” 以下, “es6” 或 “es201” 模式是無效的. 如果你選擇的 “target” 是 “es6”, 目前合法的模式也就只有 “es6”, 如果 “target” 不是 “es6”, 則 “module” 內定會是 “commonjs”. 因為是
node
, 所以沒疑問就是 “commonjs”.
- moduleResolution: 指示採用何種方式取得模組, 可用的值有 “node”, “classic”, 內定值是"classic". 因為我們是在
node
上開發, 所以最好是加上 {moduleResolution:"node"}
. -其他就有需要時再參考文件.
再來是檔案的部分,
- 如果都沒有指定
tsc
會轉譯所有目錄與其子目錄下的所有 TypeScript (*.ts or *.tsx) 檔案.
- 有 “files”, 只 會轉譯所有吻合 “files” 的檔案. 有 “exclude”, 會轉譯所有不吻合 “exclude” 的 TypeScript 檔案.
- 如果同時有 “exclude” 和 “files” 的條件, 則 “files” 優先.(不考慮 “exclude” 的條件)
- “exclude” 排除的可以是目錄, 但 “files” 只能是檔案. 而且都不支援 glob.
- “filesGlob” 支援
glob
, 可以取代 “exclude” 和 “files”. 但只有 AtomTypeScript 才支援.
- “include” 支援
glob
, 但 TypeScript 要版本 2.0 以後.
新的"tsconfig.json", 如下
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"moduleResolution": "node",
"noImplicitAny": false,
"sourceMap": false
},
"files": [
"helloAnybody.ts"
]
}
當你執行 tsc -p .
會出現 helloAnybody.ts(1,20): error TS2307: Cannot find module 'lodash'.
, 這是因為缺乏定義檔, 將之改為
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"moduleResolution": "node",
"noImplicitAny": false,
"sourceMap": false
},
"files": [
"helloAnybody.ts",
"typings/index.d.ts"
]
}
即可.
接下來安裝 async
, 照例使用 typings install async --save
, 卻發生錯誤. 這是因為 typings
對定義檔的 source 有區分. 大致上可以分為
- external,
- npm 來自 NPM, 內定使用
- github 來自 GitHub
- bitbucket 來自 Bitbucket
- bower - 來自 Bower
- common - 未知來源的基本函式庫
- shared - 共享函式庫
- global,
- lib 程式環境的共享函式庫
- env 程式環境
- global 全域的函式庫
- dt 來自 DefinitelyTyped
來源可以~
或 --source
指定. 但屬於 global 類別的要再加上--global
參數. 可以在安裝前使用typings search
查詢一下.
> typings search async
/*
Viewing 9 of 9
NAME SOURCE HOMEPAGE SCRIPTION VERSIONS UPDATED
async dt https://github.com/caolan/async 1 2016-08-04T11:33:11.000Z
......
*/
將"helloAnybody.ts"改成為非同步版本.
import * as _ from "lodash";
import * as async from "async";
var helloAsync = (compiler: string, callback: (...args: any[]) => void) => {
console.log(`Hello, ${compiler}`);
return callback();
}
var anybody = ["TS", "JS", "Node"];
async.each(anybody, helloAsync, (err) => { console.log('fin.') });
執行 tsc -p .
後, 被轉譯如下,
> cat helloAnybody.ts
/*
"use strict";
var async = require("async");
var anybody = ["TS", "JS", "Node"];
var helloAsync = function (compiler, callback) {
console.log("Hello, " + compiler);
return callback();
};
async.each(anybody, helloAsync, function (err) { console.log('fin.'); });
*/
如果你使用的函式庫沒有定義檔, 而你也不在乎是否在開發環境或轉譯時檢查該函式庫的型別, 你可以更簡單的使用 --allowJs
或在tsconfig.json
加入 {compilerOptions: {allowJs : true}}
. 這樣你就能告別 error TS2307
.
最後, 你可以使用 -w
來使檔案變動後能自動轉譯為 JS.
> tsc -w -p .
//11:46:57 - Compilation complete. Watching for file changes.
但 -w
是一開始就會決定要監控哪些檔案, 所以就算你使用支援 glob
的 include
, 後來才新增加的檔案就算符合條件也不會被監控, 要能監控新增檔案可用 gulp.watch
之類的方式來處理.
npm
安裝完 typescript 與 typings 後, 開始寫第一個程式: hello.ts. 沒看錯附檔名要從熟悉的 .js
改為 .ts
. 就讓我們寫一個有 typescript
風格的程式碼吧, 如下var hello = (word: string) => {
console.log(`Hello, ${word}`);
}
hello("TypeScript");
> tsc hello.ts; cat hello.js
/**
var hello = function (word) {
console.log("Hello, " + word);
};
hello("TypeScript");
*/
node hello.js
即可.lodash
還是 async
, 沒有了, 可是會直接降低一階的生產力. 雖然 ES6 新增的 Generator 和部分方法可替代, 但畢竟是在過度期, 並不是全部的環境都支援, 熟悉與法也需要一段時間. 這時候就輪到 typings
出場. 安裝完 typings
後, 會多出一個叫 “typings”(類似 NPM 中 node_modules 的角色) 的目錄來放 TypeScript 的定義檔.> typings init
// 會產生一個 typings.json (類似 NPM 中的 package.json)檔案.
> npm install lodash --save
// 安裝 lodash, 已經安裝了就可以略過
> typings install lodash --save
// 會將定義檔放到 "typings/modules/lodash/" 下
import * as _ from "lodash";
var hello = (compiler: string) => {
console.log(`Hello, ${compiler}`);
}
var anybody = ["TS","JS","Node"];
_(anybody).each(hello);
tsc --init
產出一個 “tsconfig.json”, 如下{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false
},
"exclude": [
"node_modules"
]
}
{}
就可以了. 但如果是這樣所有的參數就會採內定值, 這可能不是我們要的. 其實如果是這樣有這個檔跟沒有是一樣的. 所以, 接下來就一些主要會用到的部分進行解釋與修改. “tsconfig.json” 主要有兩部分,tsc
應該將檔案轉譯成什麼樣的 JavaScript.tsc
要轉譯哪些檔案.node
, 所以沒疑問就是 “commonjs”.node
上開發, 所以最好是加上 {moduleResolution:"node"}
. -其他就有需要時再參考文件.tsc
會轉譯所有目錄與其子目錄下的所有 TypeScript (*.ts or *.tsx) 檔案.glob
, 可以取代 “exclude” 和 “files”. 但只有 AtomTypeScript 才支援.glob
, 但 TypeScript 要版本 2.0 以後.{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"moduleResolution": "node",
"noImplicitAny": false,
"sourceMap": false
},
"files": [
"helloAnybody.ts"
]
}
tsc -p .
會出現 helloAnybody.ts(1,20): error TS2307: Cannot find module 'lodash'.
, 這是因為缺乏定義檔, 將之改為{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"moduleResolution": "node",
"noImplicitAny": false,
"sourceMap": false
},
"files": [
"helloAnybody.ts",
"typings/index.d.ts"
]
}
async
, 照例使用 typings install async --save
, 卻發生錯誤. 這是因為 typings
對定義檔的 source 有區分. 大致上可以分為- npm 來自 NPM, 內定使用
- github 來自 GitHub
- bitbucket 來自 Bitbucket
- bower - 來自 Bower
- common - 未知來源的基本函式庫
- shared - 共享函式庫
- lib 程式環境的共享函式庫
- env 程式環境
- global 全域的函式庫
- dt 來自 DefinitelyTyped
~
或 --source
指定. 但屬於 global 類別的要再加上--global
參數. 可以在安裝前使用typings search
查詢一下.> typings search async
/*
Viewing 9 of 9
NAME SOURCE HOMEPAGE SCRIPTION VERSIONS UPDATED
async dt https://github.com/caolan/async 1 2016-08-04T11:33:11.000Z
......
*/
import * as _ from "lodash";
import * as async from "async";
var helloAsync = (compiler: string, callback: (...args: any[]) => void) => {
console.log(`Hello, ${compiler}`);
return callback();
}
var anybody = ["TS", "JS", "Node"];
async.each(anybody, helloAsync, (err) => { console.log('fin.') });
tsc -p .
後, 被轉譯如下,> cat helloAnybody.ts
/*
"use strict";
var async = require("async");
var anybody = ["TS", "JS", "Node"];
var helloAsync = function (compiler, callback) {
console.log("Hello, " + compiler);
return callback();
};
async.each(anybody, helloAsync, function (err) { console.log('fin.'); });
*/
--allowJs
或在tsconfig.json
加入 {compilerOptions: {allowJs : true}}
. 這樣你就能告別 error TS2307
.-w
來使檔案變動後能自動轉譯為 JS.> tsc -w -p .
//11:46:57 - Compilation complete. Watching for file changes.
-w
是一開始就會決定要監控哪些檔案, 所以就算你使用支援 glob
的 include
, 後來才新增加的檔案就算符合條件也不會被監控, 要能監控新增檔案可用 gulp.watch
之類的方式來處理.
沒有留言:
張貼留言