簡體   English   中英

Nodejs,TypeScript,ts-node-dev 和頂級等待

[英]Nodejs, TypeScript, ts-node-dev & top-level await

在需要頂級等待之后,我現在已經花了一個小時來尋找新錯誤的解決方案。 到目前為止我嘗試過的所有其他方法都沒有解決錯誤,例如將"type": "module"添加到 package.json 文件。

錯誤消息是啟動服務時Cannot use import statement outside a module 如果我將更改"module": "ESNext",恢復為"module": "commonjs", ,它工作正常(除了必須刪除 await 關鍵字並以某種方式重構以在沒有 await 的情況下工作)。

此外,我使用 ts-node-dev 來運行可以在 package.json 文件中看到的服務。

  • 我需要的新的package是kafkajs。
  • 節點版本:v14.9.0
  • TypeScript 版本:4.0

package.json

{
  "name": "",
  "version": "1.0.0",
  "description": "microservice",
  "main": "src/index.ts",
  "author": "",
  "type": "module",
  "license": "MIT",
  "scripts": {
    "dev": "NODE_ENV=development tsnd --respawn --files src/index.ts",
    "prod": "NODE_ENV=production tsnd --respawn --transpile-only --files src/index.ts",
    "test": "mocha --exit -r ts-node/register tests/**/*.spec.ts",
    "eslint": "eslint src/**/*.ts"
  },

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "outDir": "dist",
    "sourceMap": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "ts-node": {
    "files": true,
    "transpileOnly": true
  },
  "include": ["src/**/*.ts", "declariations/**.d.ts"],
  "exclude": ["node_modules", ".vscode"]
}

TL;DR :不要將 ECMAScript 模塊與 ts-node 或 ts-node-dev 一起使用(目前); 只需重構頂級等待

今天我跌倒了同樣的兔子洞,從無害的錯誤開始:

Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.

其結果是,我覺得傾向於編輯我tsconfig.json並設置module ,以esnext ,這反過來又迫使我設置moduleResolutionnode ,最后加type: module到我package.json 我沒有意識到(IMO 他們不應該在錯誤消息中提出這一點——你可以簡單地重構頂級等待),這將 NodeJS 的模塊解析策略從 CommonJS 切換到 ESM。 這實際上是一個大問題,原因有很多:

我覺得此時(2020 年 12 月)NodeJS 生態系統仍在從經典的 CommonJS 模塊過渡到新的 ECMAScript 模塊。 因此,其他技術,如 ts-node 或 ts-node-dev 也在過渡,支持可能不穩定。 我的建議是堅持使用 CommonJS,直到塵埃落定並且這些東西“開箱即用”。

我知道,這個問題已經很老了,但是對於像我今天早些時候所做的那樣通過這個問題的人:

我只是設法讓它工作。 不是直接使用ts-node-dev ,而是使用nodemonts-node的組合。

你需要安裝nodemonts-node ,然后假設你的入口文件是src/index.ts ,你可以使用這個命令:

nodemon --ext ts --loader ts-node/esm --experimental-specifier-resolution node src

(使用 Node v16.13.0 測試)

這是我弄清楚的關鍵帖子: https : //github.com/TypeStrong/ts-node/issues/1007

應該可以使用 ts-node 並等待頂級。

你能試試ts-node --esm {file}作為你的命令嗎?

我目前在此代碼上使用頂級 await 和 ts-node 。

我還將我的 tsconfig 目標設置為es2022並將我的 package.json 類型設置為module

知道這個問題已經有一個公認的答案,但我認為現在已經過時了(截至 2022 年 12 月)。 ts-node-esm支持仍然被標記為實驗性的。 不過,您可以輕松設置所需的流程。

https://github.com/TypeStrong/ts-node#native-ecmascript-modules ts-node 中的相關部分和代碼庫示例(如果需要): https://github.com/vishnup95/ts-node-top -level-await/tree/main

// tsconfig.json

{

    "extends": "ts-node/node16/tsconfig.json",
    "ts-node": {
        "esm": true,
        ....
        "compilerOptions": {
            "module": "ESNext",
            "target": "ES2017"
        }
    },
    "compilerOptions": {
        // Just to make the lint shut up!
        "module": "ESNext",
        "target": "ES2017"
    }
}

不要忘記package.json中的"type": "module"

請考慮更改已接受的答案/更新它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM