【问题标题】:Unable to import ESM .ts module in node无法在节点中导入 ESM .ts 模块
【发布时间】:2020-12-23 19:43:57
【问题描述】:

我一直在尝试在 nodejs 中导入一个用 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

【问题讨论】:

  • 只需从导入中删除 .js。如果您想要扩展,请参阅this。您可以从 Node JS 更改为默认支持 Typescript 的 Deno 并使用 .ts 导入路径。仅当您知道自己在做什么时才使用 Deno,因为它相对较新。
  • @CarloCorradini 抱歉,复制粘贴时出错了。我已经尝试了所有方法。 ".js"、".ts" 并删除所有扩展名。我认为在导入 ESM mdoules 时必须进行扩展。
  • compilerOptions 中的 tsconfig.json(如果不存在则创建一个)添加以下行:"module": "commonjs"。打字稿信息页面here。 Tsconfig 信息页面here.
  • 已经是这样了。我在帖子中添加了 tsconfig。
  • 我创建了一个简单的例子here。您试图在不使用类 Util 的情况下调用函数日志。更多文档here.

标签: javascript node.js typescript ecmascript-6 nestjs


【解决方案1】:

2021 年 5 月 23 日更新

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

回答

您似乎希望将 ESM 与 Node 和 TS 一起使用。

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

tsconfig.json

确保在您的 tsconfig.json 文件中进行以下设置:

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

package.json

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

{ 
    ...
    "type":"module",
    ...
}

使用转译文件运行它

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

此外,在运行它时,请确保使用标志 --experimental-specifier-resolution=node,因为它可以让您在没有扩展的情况下进行导入,就像在 TypeScript 中发生的那样:

node --experimental-specifier-resolution=node index.js

更多详情请阅读https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm

用 ts-node 运行它

TS Node 是一个运行时转译器​​,因此它允许您在使用节点时在运行时导入 typescript 文件。

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

要安装它,您需要运行:

npm i -D ts-node 

要运行支持新分辨率模式的服务和您需要运行的 TSNode 加载器:

node --experimental-specifier-resolution=node --loader ts-node/esm index.ts

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

import {log} from './Util'

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

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

【讨论】:

    猜你喜欢
    • 2021-11-23
    • 2023-01-31
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 2015-08-12
    • 2022-01-20
    • 1970-01-01
    相关资源
    最近更新 更多