javascript - ts-node 和 ESM:未知的檔案副檔名 '.ts'
我在使用 ts-node 和 ESM 構建專案時遇到了極大的困難。關於這個主題已經有好幾個其他問題,但我嘗試了它們的所有解決方案都沒有任何進展。很難判斷哪些資訊已經過時,大部分答案都涉及在配置中添加額外的選項,但在我的情況下似乎沒有任何效果。
這裡是演示設置:
節點 v20.4
Package.json 的類型為:"module"
作為我目前使用的啟動腳本,我使用 npx ts-node-esm src/index.ts
ts-node 和 Typescript 都已經在專案本地安裝
tsconfig.json 如下:
{
"compilerOptions": {
"target": "ESNext",
"baseUrl": ".",
"esModuleInterop": true,
"moduleResolution": "NodeNext",
"module": "ESNext",
},
"types": ["node"]
}
以及我們的示範檔案 - src/index.ts:
import { sayHi } from "src/helpers.js";
sayHi();
以及 src/helpers.ts:
export function sayHi() { console.log('hi!') }
到目前為止,我目前在運行時遇到的錯誤是 Unknown file extension ".ts" for src\index.ts
(我已經了解到 'tsx' 很可能可以正常運作,但如果這裡有我自己的配置錯誤,我想了解到底出了什麼問題。)
除了眼前的實際問題之外,我也不介意得到一些更廣泛的建議。這樣做真的合理嗎?我所讀到的所有資料都建議新的專案應該使用 ESM,因為 CommonJs 並沒有特別的優勢(前提是你能讓 ESM 正常運作……)。同時,ts-node(或類似工具)的功能在快速開發反饋循環中似乎非常重要。考慮到這兩個事實,我對自己設置時遇到這麼多麻煩感到驚訝。
答案#1
Node.js v20.11.0(當前 LTS 版本)與 ts-node v10.9.2(當前版本)存在許多不相容之處。歸結如下:
使用 Node.js 18 與 CommonJS 時,您可以使用以下啟動腳本:
ts-node src/main.tsnode --require ts-node/register src/main.ts
當使用 Node.js 18 和 ESM 時,您可以使用:
ts-node-esm src/main.tsnode --loader ts-node/esm src/main.tsnode --no-warnings=ExperimentalWarning --loader ts-node/esm src/main.ts(如果你不想看到實驗性警告)
當使用 Node.js 20 和 ESM 時,你不能再使用 ts-node-esm(它會顯示 ERR_UNKNOWN_FILE_EXTENSION)。你必須使用:
node --loader ts-node/esm src/main.ts
不幸的是,這將不再給你堆疊追蹤。所以如果有編譯器錯誤,你將只能看到:
internalBinding('errors').triggerUncaughtException
在這種情況下,TypeScript 執行器 tsx 無濟於事,因為它不提供類型檢查功能。
你可以透過結合使用 tsc 和 ts-node 來解決這個問題,例如:
tsc --noEmit && node --loader ts-node/esm src/main.ts
我也做了一個教學,展示每個步驟:
- https://www.youtube.com/watch?v=jn370WEIvjs
答案#2
這並不是一個配置錯誤本身——ts-node 與 esm 在這個特定時間點就是無法與 Node 20 很好地配合。使用 node --loader ts-node/esm src/index.ts 確實是可行的,依據 https://github.com/TypeStrong/ts-node/issues/1997,也可以回到 LTS 版本。