babel-nodeとtscでdeno runみたいなことをNode.jsでしたい
はじめに
Denoを使っていて、ちょっとファイルを加工して画面に出す、みたいな1ファイルなTypeScriptを書いて deno run hoge.ts
するのが便利でした。そういったことを、Node.jsでできないかな〜と思い、最小限でやってみました。
$ yarn init
yarn init v1.22.17
# ... ひたすらEnter
babel-node
Node.jsのCLIで、Babelのpresetやpluginを使ったコンパイルした上で実行するbabel-node
を入れます。
$ yarn add -D @babel/core @babel/node
$ yarn babel-node
# ...
babel >
TypeScriptからJavaScriptに変換する@babel/preset-typescriptと、新しい文法を使えるようにしてくれる@babel/preset-envを入れます。
yarn add -D @babel/preset-env @babel/preset-typescript
これらを .babelrc
のpresetsに追加します。
{
"presets": ["@babel/preset-env", "@babel/preset-typescript"]
}
ためしに実行してみましょう。以下のようなhello worldなスクリプトを用意しました。
const greet = (msg: string) => {
return `Hello, ${msg}!`;
}
console.log(greet(["World"]));
babel-nodeに --extensions ".ts"
オプションをつけて実行します。
$ yarn babel-node --extensions ".ts" index.ts
# ...
Hello, World!
✨ Done in 0.98s.
無事に実行されました。greet
関数の引数である msg
の型は string
であるのに、Arrayを渡してもエラーになりませんでした。preset-typescriptは、変換のみを担うので、型が間違っていても実行できます。型チェックは別で行う必要があります。
tsc
TypeScriptのコンパイラであるtscをインストールします。
$ yarn add -D typescript
tscでは --noEmit
オプションをつけることで、型チェックのみを行えます。先程のスクリプトを型チェックしてみると...
$ yarn tsc --noEmit index.ts
# ...
index.ts:5:19 - error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'string'.
5 console.log(greet(["World"]));
~~~~~~~~~
Found 1 error.
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
無事に型エラーが検出されました。これをpreset-typescriptと組み合わせて、スクリプトの型チェックと実行を行います。
npm scripts
package.json
のscriptsに、型チェックと実行を書いて行きます。
{
...
"scripts": {
"deno:typecheck": "tsc --noEmit",
"deno:exec": "babel-node --extensions \".ts\""
}
...
}
これら2つのscriptをまとめて実行するために、npm-run-allを入れます。
$ yarn add -D npm-run-all
scriptsに書き足します。npm-run-allでは --
でコマンド引数を受け取り {1}
のようにして、他のscriptに渡せます。
{
...
"scripts": {
"deno:typecheck": "tsc --noEmit",
"deno:exec": "babel-node --extensions \".ts\"",
"deno-run": "npm-run-all -s \"deno:* {1}\" --"
},
...
}
実行
準備が整ったので、先程のスクリプトを実行してみましょう。
$ yarn deno-run index.ts
# ...
index.ts:5:19 - error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'string'.
5 console.log(greet(["World"]));
~~~~~~~~~
Found 1 error.
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ERROR: "deno:typecheck index.ts" exited with 2.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
エラーが2個でちゃうのがアレですが、ちゃんと型チェックで止まりました。文字列を渡すようにスクリプトを修正します。
const greet = (msg: string) => {
return `Hello, ${msg}!`;
}
// console.log(greet(["World"]));
console.log(greet("World"));
無事に実行されます。
$ yarn deno-run index.ts
# ...
Hello, World!
✨ Done in 5.32s.
babel-nodeとtscで deno run
コマンドが実現できました!!
まとめ
package.jsonと.babelrcは以下のようになりました。
{
"name": "hoge",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"deno:typecheck": "tsc --noEmit",
"deno:exec": "babel-node --extensions \".ts\"",
"deno-run": "npm-run-all -s \"deno:* {1}\" --"
},
"devDependencies": {
"@babel/core": "^7.16.0",
"@babel/node": "^7.16.0",
"@babel/preset-env": "^7.16.0",
"@babel/preset-typescript": "^7.16.0",
"npm-run-all": "^4.1.5",
"typescript": "^4.4.4"
}
}
{
"presets": ["@babel/preset-env", "@babel/preset-typescript"]
}
おわりに
ts-nodeを使えば良いのでは??...そのとおり!!
$ yarn add -D typescript ts-node
$ yarn ts-node index.ts
# ...
Hello, World!
✨ Done in 1.90s.
わけあってpreset-typescriptとtscでやりたかったんですわ...
Discussion