javascript - 無法在 node 中導入 ESM .ts 模組
我一直在嘗試在 Node.js 中導入一個用 TypeScript 編寫的 ESM 模組。但我遇到了以下錯誤:
An import path cannot end with a '.ts' extension.
Util.ts
export class Util {
constructor ( ) {
}
log(msg) {
console.log(msg)
}
}
index.ts
import {log} from './Util.ts'
log(task.query.criteria, payload.parameters)
我也在 package.json 中加入了 "type":"module"
我把 .ts 改成 .js 只是為了看看能否運作,然後我得到了:
Object.defineProperty(exports, "__esModule", { value: true }); ^
ReferenceError: exports is not defined
at file:///C:/Users/abc/NestJsPOC/NestPOC/dist/main.js:2:23
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true
}
}
編輯
我也嘗試過:
var log = require('../utility/util.js');
Util.js
function log(msg) {
console.log(msg)
}
module.exports= { log}
index.ts
log('hello')
錯誤:
TypeError: log is not a function
答案#1
過去幾年裡,我多次嘗試了我能找到或想到的每一種解決方案,而我剛剛找到了以下這個套件,它開箱即用,無需任何額外設定:
https://www.npmjs.com/package/tsx
它就是有效的:
npm i -D tsx
npx tsx src/index.ts
答案#2
更新於 2022 年 9 月 14 日
我已經建立了一個儲存庫,包含直接透過 ts-node 或使用 tsc 並使用 NodeJS 執行轉譯後的 esm 檔案所需的設定。https://github.com/felipeplets/esm-examples
請記住,您需要使用 ts-node 10+ 和 NodeJS 12+ 才能使用以下設置。
在我回答你的問題時(更新於 2022 年 5 月 29 日)更新的設定是:
原始答案
看起來你正在尋找如何在 Node 和 TS 中使用 ESM。
tsconfig.json(已使用 TypeScript 4.7 和 4.8 測試)
在你的 tsconfig.json 文件中,請確保具有以下設定:
{
"compilerOptions": {
"lib": ["ES2022"], // ES2020 in earlier versions
"module": "ES2022", //ESNext
"moduleResolution": "Node",
"target": "ES2022", // ES2020 in earlier versions
"esModuleInterop": true,
...
},
...
}
package.json
請確保在您的 package.json 文件中具有以下屬性。
{
...
"type":"module",
...
}
使用轉譯後的檔案運行它
你無法在 NodeJS 中直接匯入 .ts 檔案,你需要先使用 tsc 將它轉譯,之後才能在 NodeJS 的運行時匯入,因此最終你會匯入的是 .js 而不是 .ts 檔案。(如果要以 .ts 執行,請務必閱讀我答案的下一部分。使用 ts-node 執行)
在運行它時,你需要使用標誌 --experimental-specifier-resolution=node,因為這將允許你像在 TypeScript 中一樣使用沒有擴展名的導入:
node --experimental-specifier-resolution=node index
請注意,標誌的順序很重要 — 你 必須 在檔案路徑之前放置它。
你可以在 https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm 找到關於這個標誌的更多詳細信息
使用 ts-node 執行它
ts-node 是一個運行時轉譯器,因此它允許你在使用 node 時在運行時導入 TypeScript 文件。
ts-node 有一個功能允許你使用 ESM 來運行它,要使用這個功能,你需要安裝 TS Node 9.1 以上版本。關於實現方式和可能的問題,詳情請查看:https://github.com/TypeStrong/ts-node/issues/1007
要安裝它,您需要運行:
npm i -D ts-node
要運行支援新的解析模式和 TSNode 載入器的服務,您需要運行:
ts-node 10.8+
你可以在你的 tsconfig 檔案中加入 esm 和 experimentalSpecifierResolution。
{
...
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node"
}
}
現在你只需運行:
ts-node index
或者你可以設定 ts-node --esm 或 ts-node-esm,以在不設定 tsconfig.json 文件的情況下達到相同的效果。
ts-node 最高至 10.7
node --experimental-specifier-resolution=node --loader ts-node/esm index.ts
在此之後,你將能夠在專案中於執行時使用 TS 和 ESM,並且這個語句將會成為可能:
import { helloWorld } from './Util'
其中 helloWorld 是從 Util.ts 匯出的成員
重要! 我不建議在生產環境中使用 ts-node,所以這對開發環境非常方便和有用,但請確保在生產環境中將其轉譯並使用生成的代碼,以避免 TS Node 可能引起的記憶體問題。
