🤔

コマンドラインからtsファイルを動かすためにpackage.jsonを理解する

2021/12/16に公開

背景

ts-nodeを使うとtsファイルをコマンドラインから動かすことができる(型チェックもきく)ので便利です。便利だなと思って脳死で動かそうとしたらつまりました。
バッチで動かすこと自体は以下の記事を参考にして動かしました。
https://qiita.com/katai5plate/items/e2849d872f3dab097c68

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になります。ここで意識すべきは
https://blog.hiroppy.me/entry/nodejs-esm
こちらの記事にある

import {x} from 'y'の書き方はできません。

で、古いサンプルコードからもってくるときにimportをちょっと変える必要があります。

エラーの解消

https://qiita.com/katai5plate/items/e2849d872f3dab097c68
この記事を参考に'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にログが出ていることがあります。

蛇足

バッチを書いたらテストも書きたいですよね?
https://qiita.com/mangano-ito/items/99dedf88d972e7e631b7
この記事を参考にするとできました。ts-nodeでテストする場合もjestを入れてtransformなどの設定をすれば大丈夫で、特殊なコマンドを打つとかjestのtsバージョンのライブラリを使うみたいなことはありません。

感想

TypeScriptとかJavaScriptは他の言語より歴史が大事で、変更履歴を把握していないとつらい言語だなあと感じます。

Discussion