エラーの内容モダンな ES Modules(ESM)を利用するために、package.jsonに"type": "module"を追加したばかりかもしれません。しかし、TypeScriptファイルを実行しようとした瞬間、Node.jsがクラッシュします。コードが実行される代わりに、ランタイムは以下のような厄介な拡張子エラーをスローします。
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: /path/to/file.ts に対する未知のファイル拡張子 ".ts"
at new NodeError (node:internal/errors:399:5)
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:79:11)
原因Node.jsはTypeScriptをネイティブでサポートしていません。ES Modules(ESM)を有効にすると、Node.jsは.js、.mjs、.jsonファイルのみを認識する厳格なローダーを使用します。従来のCommonJSシステムとは異なり、ESMローダーは特定のフラグなしではts-nodeがランタイムに簡単にフックすることを許可しません。
node script.tsを実行すると、Node.jsは拡張子を確認して即座に停止します。ESMのコンテキストでは、.tsファイルをどう扱えばよいか単に分からないのです。
解決策1: 'tsx' を使用する(現代の標準)開発において、現在最も信頼できるツールはtsxです。これはesbuildをベースにしたNode.jsのドロップイン代替ツールで、従来のts-nodeよりも最大10倍高速です。追加の設定なしでESMとTypeScriptを処理できます。
1. tsxをインストールする```
npm install --save-dev tsx
### 2. ファイルを実行する`node`や`ts-node`を`tsx`に置き換えるだけです。
npx tsx ./src/index.ts
`tsx`がバックグラウンドで必要なローダーを自動的に登録するため、これで動作します。複雑なフラグや実験的機能(experimental)の警告を管理する必要はありません。
## 解決策2: ESMローダーで 'ts-node' を使用するワークフローが`ts-node`に依存している場合は、Node.jsに対してESMローダーをどのように処理するかを明示的に伝える必要があります。使用するコマンドは、特定のNode.jsバージョンによって異なります。
### Node.js v20.6.0以降またはv18.19.0以降の場合最近のアップデートで`--import`フラグが導入されました。これはTypeScriptサポートを登録するための、安定した現代的な方法です。
node --import ts-node/register ./src/index.ts
### 古いNode.jsバージョンの場合(v16.xまたは初期のv18)実験的なローダーフラグを使用する必要があります。Node.jsはこの機能が実験的であるという警告を表示することに注意してください。
node --loader ts-node/esm ./src/index.ts
### tsconfig.jsonを更新する`ts-node`をESMで動作させるには、`tsconfig.json`に特定の`ts-node`設定ブロックが必要です。
{ "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" }, "ts-node": { "esm": true } }
## 解決策3: 本番環境での修正(トランスパイル)`.ts`ファイルを直接実行するのは開発中には便利ですが、本番環境ではリスクがあります。最も堅牢な方法は、デプロイ前にコードを標準のJavaScriptにコンパイルすることです。
### 1. プロジェクトをビルドする```
npx tsc
2. 出力されたファイルを実行するコンパイルが完了したら、ビルドフォルダ(通常はdistやout)にあるJavaScriptを実行します。
node dist/index.js
出力は標準的な.jsであるため、Node.jsのESMローダーは問題なく処理します。注意: ESMモードでは、ソースファイルが.tsであっても、TypeScriptのimport文には.js拡張子を含める必要があります。
動作確認修正されたか不安な場合は、check.tsという名前のファイルを作成し、以下のコードを追加してください。
const message: string = "ローダーが動作しています!";
console.log(message);
npx tsx check.tsを実行します。スタックトレースが表示されずにメッセージが表示されれば、環境の準備は完了です。
重要なポイント
- import文で.jsを使用する: ESMでは完全なファイル拡張子が必要です。常に
import { tool } from './tool.js';のように記述してください。 - .mtsを試す:
.mts拡張子を使用すると、package.jsonの設定に関わらず、Node.jsはそのファイルをES Moduleとして扱います。 - 常に最新の状態を保つ: Node 18より古いバージョンを使用している場合は、より安定した
--importフラグを利用できるv20以降へのアップグレードを検討してください。

