コマンドラインからtsファイルを動かすためにpackage.jsonを理解する
背景
ts-nodeを使うとtsファイルをコマンドラインから動かすことができる(型チェックもきく)ので便利です。便利だなと思って脳死で動かそうとしたらつまりました。
バッチで動かすこと自体は以下の記事を参考にして動かしました。
ERR_UNKNOWN_FILE_EXTENSIONエラー
./node_modules/.bin/ts-node index.ts
ある日、上記コマンドを走らせると
ERR_UNKNOWN_FILE_EXTENSION
で落ちるようになりました。そもそもこれはpackage.jsonに"type":"module"
を設定したために起きているのですが、そもそも"type":"module"
とはなんぞやというところの説明をします。
ES Modules
Node.jsではES Modules(ESM)とCommonJS(CJS)という2種類のモジュールを扱うことができ、"type":"module"
とするとESMになります。ここで意識すべきは
こちらの記事にある
import {x} from 'y'の書き方はできません。
で、古いサンプルコードからもってくるときにimportをちょっと変える必要があります。
エラーの解消
'node --experimental-loader=ts-node/esm --es-module-specifier-resolution=node path/to/index.ts
を実行したところ、そっと死ぬようになりました。Docker上で動かしていたので以下のように問題を切り分けました。プロセスなのか、コンテナなのか、OS自体なのかあたりを考えるとよさそうです。
- Docker上での実行とローカルでの実行に差分があるか(nodeのバージョン違いによるエラーの可能性があるので)
- docker logs <コンテナid>でエラーが出ているか
- topコマンドなどで監視してメモリリークしていないか
- .npmフォルダの中にログがないか
といった風に切り分けたのですが、どこにもログが出ません。結論としては実行コードを忘れていました。main functionを作ったのにmain()をしていなくて何も走っていなかったという…とほほ。
なお、実行時にエラーが起きた際のにコマンドラインに出ない場合(fsでファイル権限で落ちた時などがあたりそうです)、.npmにログが出ていることがあります。
蛇足
バッチを書いたらテストも書きたいですよね?
この記事を参考にするとできました。ts-nodeでテストする場合もjestを入れてtransformなどの設定をすれば大丈夫で、特殊なコマンドを打つとかjestのtsバージョンのライブラリを使うみたいなことはありません。感想
TypeScriptとかJavaScriptは他の言語より歴史が大事で、変更履歴を把握していないとつらい言語だなあと感じます。
Discussion