类型脚本: 不能在模块外使用导入语句

我有一个。节点 js (node.js 的最新版本,用于07.10.19)应用程序中的 ts 文件,导入 node-module 而没有默认导出。我使用这个结构: 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
}
}
233435 次浏览

更新: 因为这个答案获得了重要的观点,我已经更新了它,以便更好地展示2022年这个问题的可用解决方案。


这个错误意味着 Node 在一个文件中发现了一个 import语句,它没有考虑 ECMAScript (ES)模块。将 ABC1添加到 package.json将告诉 Node 您正在使用 ES 模块,但是您需要通过在 tsconfig.json中设置 "module": "es2015"或更高(例如: "es2020")来告诉 TypeScript 编译器发出这种类型的模块。如果要发出 CommonJS 模块(require) ,请设置 "module": "commonjs"

如果您不想在项目级别设置模块系统,还有更多细粒度的选项。扩展名为 .mjs的文件始终被视为 ES 模块,而扩展名为 .cjs的文件始终被视为 CommonJS 模块。从 TypeScript 4.5开始,也可以使用 .mts.cts扩展,并让编译器分别发出 .mjs.cjs文件。

这两个系统部分兼容。例如,可以将 CommonJS 模块导入具有默认导出的 ES 模块:

// in an ES module
import thing from "./main.cjs";

正好相反。可以将 ES 模块导入具有动态导入功能的 CommonJS 模块(需要 ES2020特性才能正常工作) :

// in a CommonJS module
const thing = await import("./main.mjs");

原答案(2020) :

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

但是,这会导致当前代码出现问题,因为尽管您使用的是 ES6 import {}语句,但是您使用的是 commonJS module.exports = {}语法导出,而 Node 的 ES 模块加载程序会出现问题。有两种方法可以解决这个问题:

  • 保留 module.export,但告诉 Node 通过给它一个. cjs 扩展名来将该文件解释为 commonJS。
  • 将导出语句更改为 ES2015语法: export function execute(…)..

第一个选项可能有点棘手,因为编译器将输出。Js 文件,你必须把它改成。一直都是 cjs (据我所知)。使用第二个选项,您应该能够使用 Node 运行该文件(包括版本 < 13.8的实验模块标志)。

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

有很多种可能性,

SyntaxError: 不能在模块外使用 import 语句

在运行打字稿的时候。

在我的设置中,我从脚本 testab.ts导入了一个名为 AbModule的模块(AbModule具有类 AbClassName)。

testab.tsimport stmt,

import {AbClassName} = 'testAdapterDir/AbModule.po.ts';

但是, AbModule有所有的 *.ts文件,有 *.js文件不存在。 解决办法是,

运行下面的代码可能会出错,但是可以安全地忽略它们。

cd AbModule path
tsc *.ts

现在 AbModule也应该包含所有 *.js编译过的文件。 现在运行 testab.ts并注意到上面提到的错误不再存在,

确保 package.json中的 "main"字段指向已编译的 index.js而不是 index.ts

我有非常相似的问题。我必须安装 不是恶魔和始终通过 nodemon index.ts启动脚本

yarn add -D nodemon

包裹 Json

"scripts": {
"start": "nodemon index.ts"
}

或从命令行指定文件

包裹 Json

"scripts": {
"nodemon": "nodemon $1"
}

如果正好使用 ts-node,可以在 tsconfig.json中专门为 ts-node设置一些编译器选项。

{
"ts-node": {
// these options are overrides used only by ts-node
// same as the --compilerOptions flag and the TS_NODE_COMPILER_OPTIONS environment variable
"compilerOptions": {
"module": "commonjs"
}
},
"compilerOptions": {
"module": "esnext"
}
}

然后你可以很容易地执行你的脚本:

$ ts-node my-script.ts

tsconfig.json集:

  "ts-node": {
"compilerOptions": {
"module": "CommonJS"
}
}