はじめに
tsファイルをコマンドで叩いて実行する際に、表題のエラーになりました。
解決に時間がかかってしまったため、備忘録としてまとめます。
問題
npx ts-node --esm ./batch/index.ts
コマンドを実行するとTypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for
が発生する
コマンドの意味を理解
- npx:Node.jsのパッケージをインストールすることなく実行できる
-
ts-node --esm:
ts-node
はTypeScriptファイルを直接実行できるツール(JavaScriptに変換してくれる)、--esm
は「ESモジュールモードで実行してください」を指定 - ./batch/index.ts:実行するファイルパス
原因
Node.jsはjavascriptを実行するプログラム、Node.jsは「.ts」がなんのファイルか認識できていなかったことが原因でした。
ts-node --esm
でJavaScriptに変換して実行してくれるのでは?となりました。
-
--esm
で指定したESモジュールモードは、拡張子の扱いが厳格だそうです。
特に、import文など(import {} from './module.js'
)では必ず拡張子の指定が必要になります。(CommonJSモードはrequire('./module')
のように拡張子を省略できる) -
ts-nodeはコンパイル時に.tsを
.js
に変換しますが、コード内のインポート文の拡張子は自動的に修正しません
ファイル内で、import文を使用している場合、Node.jsはimport内の「.ts」を認識できず、エラーとなります
解決方法
npx tsx ./batch/index.ts
で実行する
tsx
はTypeScriptをJavaScriptに自動的に変換してくれます。
また、ts-node --esm
では解決できないインポート文の拡張子問題なども自動的に解決してくれます。
ファイル拡張子の「.tsx」とは違う
今回使用したのはコマンドラインツールの「tsx」
JSX記法のTypeScriptバージョンの拡張子「.tsx」と全く同じ名前ですが異なります
おわりに
コマンドのtsxとJSX記法のtsxは違うよね?あっているよね?ってなりました。
参考