我在 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
语句是文件中的第一行吗?
require
与 import
)而有所不同。为了让您了解这有多复杂,Node 提供了一些关于 import
与 require
以及如何使它们协同工作的 documentation。
module.exports
语法,您可能不在 ES6 模块中。
execute(a : abc.Class...
时找不到命名空间“abc”
更新:因为这个答案获得了重要的意见,我已经更新了它,以更好地展示 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 是明确的)。
如果您碰巧使用 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
确保 package.json
中的 "main"
字段指向已编译的 index.js
而不是 index.ts
我有非常相似的问题。我必须安装 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
语句。
获得的可能性有很多,
SyntaxError: 不能在模块外使用 import 语句
在运行打字稿时。
在我的设置中,我从我的脚本 testab.ts
中导入了一个名为 AbModule
(AbModule
具有类 AbClassName
)的模块。
testab.ts
有 import stmt
,
import {AbClassName} = 'testAdapterDir/AbModule.po.ts';
但是,AbModule
拥有所有 *.ts
个文件,并且有 *.js
个文件不存在。修复是,
您可能会在运行以下代码时遇到错误,但您可以放心地忽略它们。
cd AbModule path
tsc *.ts
现在 AbModule
也应该包含所有已编译的文件 *.js
。现在运行 testab.ts
并注意到上述错误不再存在,
在 tsconfig.json
集中:
"ts-node": {
"compilerOptions": {
"module": "CommonJS"
}
}
不定期副业成功案例分享
module.exports
那么你只需要阅读第一段。"type": "module"
:D