ts-node を試す
作業を効率化するためにちょっとしたスクリプトを書くことがある。その際いつもプログラミング言語と実行環境に Node.js を採用していたのだが、これを TypeScript 化したくなった。とはいえ小規模なスクリプト程度で実行前にコンパイルするのは面倒。なのでこれらを自動処理してくれるという TypeStrong/ts-node を試してみた。
環境構築
スクリプト実行用のプロジェクトを作成する。適当なディレクトリー内で npm init
を実行して package.json
を生成、その後に TypeScript 設定ファイル tsconfig.json
とスクリプト本体の index.ts
を用意。
.
├── index.ts
├── package.json
└── tsconfig.json
必要最小の npm をインストール。
$ npm i ts-node typescript @types/node
それぞれの役割をまとめる。
npm | 役割 |
---|---|
ts-node | 指定された TypeScript ファイルをコンパイルして実行するための CLI ツール。 |
typescript | TypeScript コンパイラー。 |
@types/node | Node.js 由来の機能やモジュールに対する型情報。 |
ts-config.json
を定義。現時点で最新の Node.js 12 系を想定して target
を ES2017、チェック系は私の好みで厳しくしてある。雑なスクリプトなら noImplicitAny
とか strictNullChecks
は false
でもよいだろう。
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"noImplicitAny": true,
"strictNullChecks": true,
"moduleResolution": "node",
"declaration": true,
"sourceMap": false,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"*": ["node_modules/*"]
}
}
}
プロジェクトのローカルにある ts-node
でスクリプトを実行させるため、コマンドを package.json
の npm-scripts へ定義する。諸々、含めた全体は以下。
{
"name": "my-tool",
"version": "1.0.0",
"description": "My tool.",
"author": "akabeko",
"license": "UNLICENSED",
"private": true,
"scripts": {
"exec": "ts-node index.ts"
},
"dependencies": {
"@types/node": "^12.6.8",
"ts-node": "^8.3.0",
"typescript": "^3.5.3"
}
}
これで npm run exec
を実行すれば index.ts
を ts-node
が自動的にコンパイル & 実行してくれる。タイプ量を減らしたければ
{
"scripts": {
"start": "npm run exec",
"exec": "ts-node index.ts"
}
}
として npm start
で実行するのもよいだろう。start
や test
などは npm-scripts に予約されたコマンドで npm run
の run
を省略できる。
コマンドライン引数
スクリプトに対して動的に引数を与えて振る舞いを変えたくなった場合、どうすればよいか。これは npm-scripts 内へ指定したものをそのまま ts-node 経由でスクリプトに渡せる。
{
"scripts": {
"exec": "ts-node index.ts --foo"
}
}
しかしこの方法だと引数を分岐させるために npm-scripts を修正するか複数定義しなければならず面倒。そのため npm-scripts 自体へ渡された引数を指定できるようにしたい。その方法は npm-run-script に紹介されている。
$ npm run exec -- --bar
このように --
を付けた後に引数を指定すれば、それを npm-scripts 側へそのまま渡してくれる。ちなみに npm-scripts 内でも引数を指定していた場合、
- npm-scripts 内の引数
- npm-scripts 実行時の引数
の順で渡される。例えば前述の npm-scripts と引数指定で
console.log(process.argv);
という TypeScript を実行したなら
$ npm run exec -- --bar
> my-tool@1.0.0 exec .../my-tool
> ts-node index.ts --foo "--bar"
[
'.../my-tool/node_modules/.bin/ts-node',
'.../my-tool/index.ts',
'--foo',
'--bar'
]
このような出力が得られる。
まとめ
最近はこんな感じの環境で簡易スクリプトを書いたり外部 npm 選定用の検証をおこなったりしてる。TypeScript としての機能を試すのにもよい。
ts-node
などの依存はプロジェクト内で閉じているから、これを発展させてツール化した時も配布は簡単。プロジェクトのディレクトリー単位で渡して npm i
すれば準備が完了する。実に便利。