无法在节点中导入 ESM .ts 模块

Sam*_*ack 2 javascript node.js typescript ecmascript-6 nestjs

我一直在尝试在 nodejs 中导入一个用 typescript 编写的 ESM 模块。但我收到以下错误:

An import path cannot end with a '.ts' extension.
Run Code Online (Sandbox Code Playgroud)

实用程序

 export class Util {
    constructor ( ) {
       
    }
      log(msg) {
        console.log(msg) 
    }
  }
Run Code Online (Sandbox Code Playgroud)

索引.ts

import {log} from './Util.ts'
log(task.query.criteria, payload.parameters)
Run Code Online (Sandbox Code Playgroud)

我也在"type":"module"里面添加了package.json

我将 .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
Run Code Online (Sandbox Code Playgroud)

配置文件

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑

我也试过:

 var log = require('../utility/util.js');
Run Code Online (Sandbox Code Playgroud)

实用程序

    function log(msg) {
      console.log(msg)
     
  }
    module.exports= { log}
Run Code Online (Sandbox Code Playgroud)

索引.ts

    log('hello')
Run Code Online (Sandbox Code Playgroud)

错误

TypeError: log is not a function
Run Code Online (Sandbox Code Playgroud)

ele*_*vir 67

在过去的几年里,我多次尝试了我能找到或想到的所有解决方案,并且我刚刚找到了以下包,它可以开箱即用,无需任何额外的设置:

https://www.npmjs.com/package/tsx

它只是有效:

npm i -D tsx
npx tsx src/index.ts
Run Code Online (Sandbox Code Playgroud)

  • 这让我重新启动并运行,而最受欢迎的答案我无法让它与 ts-node 一起工作。你的回答效果很好。 (6认同)
  • 这次真是万分感谢!我经历了很多挣扎,直到找到这个答案。我同意,我现在讨厌 ts-node (6认同)
  • 天哪……“tsx”立即生效?!互操作性好多了……发现这个让我震惊不已。谢谢你! (5认同)
  • 哇。这应该是答案吧!!!!我现在讨厌 ts-node... (5认同)
  • 这是 100% 正确的答案。 (3认同)

Fel*_*ets 5

2021 年 5 月 23 日更新

请记住,您需要使用ts-node 10+NodeJS 12+才能使用以下设置。

回答

您似乎希望将 ESM 与 Node 和 TS 结合使用。

在我回答您的问题时更新的设置是:

配置文件

在您的 tsconfig.json 文件中,确保具有以下设置:

{
    "compilerOptions": {
        "lib": ["es2020"],
        "module": "ESNext",
        "moduleResolution": "node",
        "target": "ES2020",
        "esModuleInterop": true,
        ...
    },
    ... 
}

Run Code Online (Sandbox Code Playgroud)

包.json

确保您的package.json文件具有以下属性。

{ 
    ...
    "type":"module",
    ...
}
Run Code Online (Sandbox Code Playgroud)

使用转译的文件运行它

别忘了在NodeJS中不能直接导入TS文件,需要先使用转译tsc,然后在运行时再导入NodeJS中,所以最后导入的是js而不是ts文件。要将其作为 TS 运行,请务必阅读我的答案的下一部分。

此外,在运行它时,请确保使用该标志,--experimental-specifier-resolution=node因为它将使您能够像在 TypeScript 中那样进行没有扩展名的导入:

node --experimental-specifier-resolution=node index.js
Run Code Online (Sandbox Code Playgroud)

有关该标志的更多详细信息,请阅读https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm

用 ts-node 运行它

TS Node 是一个运行时转译器​​,因此它允许您在使用 node.js 时在运行时导入打字稿文件。

目前 TS Node 中有一个实验性功能,允许您使用 ESM 运行它,要使用它,您需要安装 TS Node 9.1+。有关实施和可能出现的问题的更多详细信息,请检查: https //github.com/TypeStrong/ts-node/issues/1007

要安装它,您需要运行:

npm i -D ts-node 
Run Code Online (Sandbox Code Playgroud)

要运行支持新解析模式的服务和 TSNode 加载器,您需要运行:

node --experimental-specifier-resolution=node --loader ts-node/esm index.ts
Run Code Online (Sandbox Code Playgroud)

在此之后,您将能够在运行时在您的项目中使用 TS 和 ESM,并且可以使用以下语句:

import {log} from './Util'
Run Code Online (Sandbox Code Playgroud)

其中 log 是从 Util.ts 导出的成员

重要的!我不建议在生产中使用 ts-node,因此这对于开发环境非常方便和有用,但请确保在生产中转译和使用生成的代码,以避免 TS Node 可能出现的内存问题。

  • 这对我没有帮助。无论我做什么,当我尝试使用“node --experimental-specifier-resolution=node --loader ts-node/esm app”运行我的代码时,我都无法超越“未知文件扩展名“.ts””。 ts`。 (4认同)