ChatGPT解决这个技术问题 Extra ChatGPT

打字稿:不能在模块外使用导入语句

我在 node js(07.10.19 的 node.js 的最新版本)应用程序中有一个 .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
  }
}
你是在浏览器中运行这个吗? import 语句是文件中的第一行吗?
你能发布你的 tsconfig.json 文件吗?当您在 Typescript 中编译时,您可以确定它生成的模块类型,有效类型可能会根据您使用的环境(浏览器/NodeJS)和其他模块(requireimport)而有所不同。为了让您了解这有多复杂,Node 提供了一些关于 importrequire 以及如何使它们协同工作的 documentation
如果您使用 module.exports 语法,您可能不在 ES6 模块中。
好的,我不能使用 require,因为使用构造 execute(a : abc.Class... 时找不到命名空间“abc”

Z
Zwiers

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

该错误表示 Node 在文件中发现了一条 import 语句,它不认为是 ECMAScript (ES) 模块。 Adding "type": "module" to 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 模块,这应该可以消除错误,但是您需要通过设置 "module": "es2015" 而不是 "commonjs" 来告诉 Typescript 生成这种类型的模块tsconfig.json

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

保留 module.exports,但告诉 Node 通过给它一个 .cjs 扩展名来将此文件解释为 commonJS。

将 export 语句改为 ES2015 语法:export function execute(…)..

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

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


对于 webpack 生成的包,我收到错误消息:“ReferenceError: require is not defined in ES module scope, you can use import instead”?我该如何防止这种情况?
自己注意:如果你从不写 module.exports 那么你只需要阅读第一段。
我反其道而行之!我将 tsconfig.json 更改为 "module" : "CommonJS" 并删除了 package.json 中的 "type":"module" 它对我有帮助:D
为什么我什至要删除 "type": "module" :D
P
PaulMest

如果您碰巧使用 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

J
Jordan Morris

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


M
Matthew Purdon

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

yarn add -D nodemon

包.json

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

或从命令行指定文件

包.json

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

这似乎对我有用(安装了 ts-node,在 package.json 中使用没有 `"type": "module" 的 import 语句。
R
Rishit Dagli

获得的可能性有很多,

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

在运行打字稿时。

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

testab.tsimport stmt

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

但是,AbModule 拥有所有 *.ts 个文件,并且有 *.js 个文件不存在。修复是,

您可能会在运行以下代码时遇到错误,但您可以放心地忽略它们。

cd AbModule path
tsc *.ts

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


m
marko424

tsconfig.json 集中:

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