无法在节点中导入 ESM .ts 模块 [英] Unable to import ESM .ts module in node

查看:94
本文介绍了无法在节点中导入 ESM .ts 模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have been trying to import an ESM module written in typescript in nodejs. But I am getting the following error:

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

我将 .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

推荐答案

2021 年 5 月 23 日更新

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

Update May 23st, 2021

Keep in mind that you need to use ts-node 10+ and NodeJS 12+ in order to use the setup below.

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

It seems you are looking to use ESM with Node and TS.

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

The updated settings to make it by the time I'm answering your question is:

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

On your tsconfig.json file make sure to have the following settings:

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

package.json

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

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

使用转译的文件运行它

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

Running it with transpiled files

Don't forget that you can't import a TS file direct in NodeJS, you need to first transpile it using tsc to then import it in the NodeJS in runtime, so in the end you will be importing the js and not the ts file. To run it as TS please make sure to read the next section of my answer.

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

Also when running it make sure to use the flag --experimental-specifier-resolution=node as it will enable you to have imports with no extensions as it happens in TypeScript:

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

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

For more details for the flag please read https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm

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

TS Node is a runtime transpiler so it allow you to import typescript files in runtime when using node.

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

Currently there is an experimental feature in TS Node that allows you to run it using ESM, to use it you will need to install TS Node 9.1+. For more details on the implementation and possible issues check: https://github.com/TypeStrong/ts-node/issues/1007

要安装它,您需要运行:

To install it you will need to run:

npm i -D ts-node 

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

And to run the service supporting the new resolution mode and the TSNode loader you will need to run:

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

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

After this you will be able to use TS and ESM in your project in runtime and this statement will be possible:

import {log} from './Util'

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

Where log is an exported member from Util.ts

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

Important! I don't recommend using ts-node in production, so this is very handy and useful for a development environment but make sure to transpile and use the resulting code in production to avoid possible memory issues with TS Node.

这篇关于无法在节点中导入 ESM .ts 模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆