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

Zer*_*umi 67 typescript ecmascript-6

我在 node js(07.10.19 的最新版本 node.js)应用程序中有一个 .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>){ ...
Run Code Online (Sandbox Code Playgroud)

这是我的 tsconfig.json:

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

    "strict": true
  }
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*est 130

如果你恰好在使用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"
  }
}
Run Code Online (Sandbox Code Playgroud)

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

{
  "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"
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 就是这样,特别是在像 create-react-app 这样带有内置 tsconfig 的项目中! (2认同)

Zwi*_*ers 30

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

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

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

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

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


Jor*_*ris 18

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


小智 7

"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": ["**/*"]
}

Run Code Online (Sandbox Code Playgroud)


Jak*_*iel 5

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

yarn add -D nodemon
Run Code Online (Sandbox Code Playgroud)

包.json

"scripts": {
   "start": "nodemon index.ts"
}
Run Code Online (Sandbox Code Playgroud)

或从命令行指定文件

包.json

"scripts": {
   "nodemon": "nodemon $1"
}
Run Code Online (Sandbox Code Playgroud)