打字稿:无法在模块外使用import语句


19

我在节点js(最新版本的node.js,适用于07.10.19)应用程序中有一个.ts文件,其中包含导入节点模块而没有默认导出的情况。我使用以下构造:import { Class } from 'abc';运行代码时,出现以下错误:Cannot use import statement outside a module

在网络中,我看到了针对此问题的许多解决方案(针对.js),但这对我没有帮助,也许是因为我有打字稿文件。这是我的代码:

import { Class } from 'abc';
module.exports = { ...
    execute(a : Class ,args : Array<string>){ ...

这是我的tsconfig.json:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",

    "strict": true
  }
}

您是否正在浏览器中运行它?是import声明在文件的第一行?
外翻

1
您能发布您的tsconfig.json文件吗?当您在Typescript中进行编译时,您可以确定它生成的模块类型,并且有效的类型可能会有所不同,具体取决于您所使用的环境(浏览器/ NodeJS)和所使用的其他模块(requirevs import)。只是为了让您了解这有多么复杂,Node拥有一些关于vs 以及如何使它们协同工作的文档importrequire
杰夫·鲍曼

1
如果使用module.exports语法,则可能不在ES6模块中。
Bergi

Evert,这是节点js应用,tsconfig将很快添加
Zerumi

好的,我无法使用require,因为使用构造时找不到命名空间“ abc”execute(a : abc.Class...
Zerumi

Answers:


5

添加“type”: “module”到package.json中将告诉Node您正在使用ES2015模块,该错误应消除,但随后您将需要告诉Typescript通过设置“module”: “es2015”而不是“commonjs”在tsconfig.json中生成这种类型的模块。

但是,这会导致当前代码出现问题,因为尽管您使用的是ES6 import {}语句,但您使用的是commonJS module.exports = {}语法进行导出,并且Node的ES模块加载器会遇到问题。有两种处理方法:

  1. 保持module.exports而是告诉节点通过解释该文件作为CommonJS的给它一个.cjs扩展
  2. 将export语句更改为ES2015语法: export function execute(…)..

第一个选项可能会有些棘手,因为编译器将输出.js文件,并且您必须一直将其更改为.cjs(据我所知)。使用第二个选项,您应该能够使用Node运行文件(包括版本<13.8的--experimental-modules标志)。

如果您绝对需要使用commonJS,也许最好为Node:@ types / node安装类型定义,然后将导入更改为commonJS格式:require('abc')并保持其余设置不变(尽管您可以添加“ type” :“ commonjs”到package.json是明确的)。


1
require('abc')。Class不能在.ts定义中使用(如:Class)...关于.cjs扩展名...类型只能在.ts文件中... ES2015也不是我的选择,因为我使用这个带有旧导入(需要)的模块无处不在...我使用JSDoc解决了这个问题。但是,感谢您的回答
Zerumi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.