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

8ehkhllq  于 2022-12-30  发布在  TypeScript
关注(0)|答案(7)|浏览(401)

我在node js(最新版本的node.js for 07.10.19)应用程序中有一个. ts文件,导入了节点模块,但没有默认导出。import { Class } from 'abc';当我运行代码时,我遇到了这个错误:Cannot use import statement outside a module.
在网络中,我看到这个问题的许多解决方案(为. js),但它对我没有帮助,也许是因为我有 typescript 文件.

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

下面是我的tsconfig.json:

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

    "strict": true
  }
}
zaqlnxep

zaqlnxep1#

  • 更新:因为这个答案越来越重要,我已经更新了它,以更好地显示在2022年这个问题的可用解决方案。*

此错误表示Node在文件中找到了一个import语句,但它不认为该语句是ECMAScript(ES)模块。将"type": "module"添加到package.json将告诉Node您正在使用ES模块,但随后您需要通过设置"module": "es2015"或更高的值来告诉TypeScript编译器发出此类型的模块(例如:tsconfig.json中的"es2020")。如果要发出CommonJS模块(require),请设置"module": "commonjs"
如果您不想在项目级设置模块体系,还有更细粒度的选项,扩展名为.mjs的文件始终被视为ES模块。而带有.cjs的文件总是被视为CommonJS模块。5也可以使用.mts.cts扩展,并让编译器分别发出.mjs.cjs文件。
两个系统部分兼容,例如CommonJS模块可以导入ES模块,默认导出:

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

反之亦然。ES模块可以通过动态导入导入到CommonJS模块中(需要ES 2020功能才能正常工作):

// in a CommonJS module
const thing = await import("./main.mjs");
原始答案(2020年):

"type": "module"添加到package.json将告诉Node您正在使用ES 2015模块,这应该会消 debugging 误,但随后您需要告诉Typescript通过在tsconfig.json中设置"module": "es2015"而不是"commonjs"来生成这种类型的模块。
但是这会导致当前代码出现问题,因为虽然您使用的是ES6 import {}语句,但您使用的是commonJS module.exports = {}语法导出,Node的ES模块加载器会出现问题。

  • 保留module.exports,但是通过给它一个.cjs扩展名,告诉Node把这个文件解释为commonJS。
  • 将export语句更改为ES 2015语法:export function execute(…)..

第一个选项可能有点棘手,因为编译器会输出.js文件,你必须一直将其更改为.cjs(据我所知)。使用第二个选项,你应该能够用Node运行文件(包括版本〈13.8的--experimental-modules标志)。
如果你绝对需要使用commonJS,也许安装Node的类型定义会更好:@types/node并将导入更改为commonJS格式:require('abc')并保持其余设置不变(尽管您可以将"type": "commonjs"添加到package.json中以使其显式)。

mcvgt66p

mcvgt66p2#

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

3pvhb19x3#

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

sxpgvts3

sxpgvts34#

我遇到了非常类似的问题。我必须安装nodemon,并且总是通过nodemon index.ts启动脚本

yarn add -D nodemon
    • 包. json**
"scripts": {
   "start": "nodemon index.ts"
}

或从命令行指定文件

    • 包. json**
"scripts": {
   "nodemon": "nodemon $1"
}
gywdnpxw

gywdnpxw5#

有很多种可能性可以得到,
语法错误:不能在模块外部使用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,注意到上述错误不再存在,

k2arahey

k2arahey6#

"type": "module"不是选项时的解决方案

  • .ts重命名为.mts
  • 运行ts-node --esm file.mts

下面是我tsconfig.json以供参考:

{
  "compilerOptions": {
    "incremental": true,
    "target": "ESNext",
    "module": "ESNext",
    "allowJs": true,
    "checkJs": false,
    "outDir": "./dist",
    "sourceMap": true,
    "strict": true,
    "alwaysStrict": true,
    "moduleResolution": "node",
    "esModuleInterop": true
  },
  "include": ["**/*"]
}
1bqhqjot

1bqhqjot7#

tsconfig.json集合中:

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

相关问题