SyntaxError: Cannot use import statement outside a module

use*_*626 10 javascript node.js babeljs apollo-server

I've got an ApolloServer project that's giving me trouble, so I thought I might update it and ran into issues when using the latest Babel. My "index.js" is:

require('dotenv').config()
import {startServer} from './server'
startServer()
Run Code Online (Sandbox Code Playgroud)

And when I run it I get the error "SyntaxError: Cannot use import statement outside a module". First I tried doing things to convince TPTB* that this was a module (with no success). So I changed the "import" to a "require" and this worked.

But now I have about two dozen "imports" in other files giving me the same error.

*我确定问题的根源在于,我甚至不确定该问题的根源。我有点以为是Babel 7(因为我来自Babel 6,所以我不得不更改预设),但我不确定100%。

我为解决方案找到的大多数内容似乎不适用于纯Node。像这里这样:

ES6模块导入,给出“未捕获的SyntaxError:意外的标识符”

说可以通过添加“ type = module”来解决,但这通常会出现在HTML中,而我没有。我还尝试使用项目的旧预设:

"presets": ["es2015", "stage-2"],
"plugins": []
Run Code Online (Sandbox Code Playgroud)

但这给了我另一个错误:“错误:插件/预设文件不允许导出对象,只能导出功能。”

更新:这是我开始的依赖项:

"dependencies": {
"@babel/polyfill": "^7.6.0",
"apollo-link-error": "^1.1.12",
"apollo-link-http": "^1.5.16",
"apollo-server": "^2.9.6",
"babel-preset-es2015": "^6.24.1",
Run Code Online (Sandbox Code Playgroud)

jab*_*tta 350

验证您是否安装了最新版本的 Node(或至少 13.2.0+)。然后执行以下操作之一,如文档中所述

选项1

在最近的父package.json文件中,添加"type"值为的顶级字段"module"。这将确保所有.js.mjs文件都被解释为 ES 模块。您可以使用.cjs扩展名将单个文件解释为 CommonJS 。

// package.json
{
  "type": "module"
}
Run Code Online (Sandbox Code Playgroud)

选项 2

使用.mjs扩展名显式命名文件。所有其他文件,例如.js将被解释为 CommonJS,如果type未在package.json.

  • 如果问题出在 node_modules/ 下,这并不是一个真正的选择,对吧?在这种情况下有什么解决办法吗? (49认同)
  • 如果您正在运行 ``.ts``` 文件,则此解决方案不起作用。如果您可以简单地使用 ```nodemon``` 而不是 ```node``` 添加这一点,按照下面的答案 /sf/answers/4554080401/ ,它有望帮助人们我已经折腾了半天了。或者,安装“ts-node”似乎是一个解决方案,根据 /sf/answers/4336350791/ (9认同)
  • 或者使用巴别塔!` module.exports = { 预设:['@babel/preset-env'], }; ` (4认同)
  • 如果我使用这个,然后更改路径以包含所需文件的“js”,然后更改所需文件中导出语句的格式,然后取出我从“导入”更改的所有“require”语句 - 因为现在“require”未知 - 这会起作用,所以我会接受这个答案。 (3认同)

Dr-*_*ket 82

如果有人在使用Typescript 时遇到这个问题,那么为我解决这个问题的关键是改变

    "target": "esnext",
    "module": "esnext",
Run Code Online (Sandbox Code Playgroud)

    "target": "esnext",
    "module": "commonjs",
Run Code Online (Sandbox Code Playgroud)

在我的tsconfig.json. 我的印象是“ esnext”是“最好的”,但这只是一个错误。

  • 你的答案有效。你能解释一下为什么我们要这样调整吗?@Dr-Bracket 谢谢你 (4认同)
  • 该死的,它让我摆脱了很多麻烦。我犯了同样的错误,因为“esnext”是最好的 (3认同)

L. *_*nye 48

对于那些在阅读答案时和我一样困惑的人,在您的 package.json 文件中,"type": "module" 在上层添加 如下所示:

{
  "name": "my-app",
  "version": "0.0.0",
  "type": "module",
  "scripts": { ...
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)

  • 但是当我添加`type: module`时,如果我使用require,我会得到一个错误:`ReferenceError: require is not Defined in ES module scope, you can use import instead` (10认同)

Kon*_*lin 36

根据官方文档(https://nodejs.org/api/esm.html#esm_code_import_code_statements):

import 语句只允许在 ES 模块中使用。对于 CommonJS 中的类似功能,请参阅 import()。

要使 Node 将您的文件视为 ES 模块,您需要(https://nodejs.org/api/esm.html#esm_enabling):

  • 将 "type": "module" 添加到 package.json
  • 在节点调用中添加“--experimental-modules”标志

  • 2020 更新:不再需要 `--experimental-modules`。 (28认同)
  • 但是当我添加`type: module`时,如果我使用require,我会得到一个错误:`ReferenceError: require is not Defined in ES module scope, you can use import instead` (4认同)
  • 并不是说这个答案是错误的,我看过相同的文档。但我不明白使用 import() 访问 CommonJS 中的 es6 模块的建议有什么用。它是异步的,因此不能用于在文件级别导入任何内容。至少可以说,这使得尝试从 CommonJS 访问 es6 模块变得很痛苦。考虑到主要的单元测试框架 Jasmine Jest 等根本不能很好地处理这个问题,这让我想到,除非有更好的互操作支持,否则整个 Node es6 的情况对我来说似乎还不够成熟,但我希望被证明是错误的。 (2认同)

us_*_*vid 24

我遇到了同样的问题,甚至更糟:我需要“导入”和“需要”

  1. 一些较新的 ES6 模块仅适用于导入。
  2. 一些 CommonJS 与 require 一起工作。

这是对我有用的:

  1. 按照其他答案中的建议将您的 js 文件转换为 .mjs

  2. ES6 模块没有定义“require”,所以你可以这样定义它:

    import { createRequire } from 'module'
    const require = createRequire(import.meta.url);
    
    Run Code Online (Sandbox Code Playgroud)

    现在'require'可以以通常的方式使用。

  3. 对 ES6 模块使用 import,对 commonJS 使用 require。

一些有用的链接: node.js's own documentationimport 和 require 之间的区别Mozilla 有一些关于导入的不错的文档


Adr*_*ian 11

Node.js v14.16.0:

对于那些尝试过 .mjs 并获得以下结果的人:

Aviator@AW:/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex$ node just_js.mjs
file:///mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex/just_js.mjs:3
import fetch from "node-fetch";
       ^^^^^

SyntaxError: Unexpected identifier
Run Code Online (Sandbox Code Playgroud)

谁尝试过import fetch from "node-fetch"; ,谁尝试过const fetch = require('node-fetch');

Aviator@AW:/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex$ node just_js.js
(node:4899) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex/just_js.js:3
import fetch from "node-fetch";
^^^^^^

SyntaxError: Cannot use import statement outside a module
Run Code Online (Sandbox Code Playgroud)

以及尝试"type": "module"过 package.json 但仍继续看到错误的人,

{
  "name": "test",
  "version": "1.0.0",
  "description": "to get fetch working",
  "main": "just_js.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "MIT"
}
Run Code Online (Sandbox Code Playgroud)

我可以毫无问题地切换到Axios 。

import axios from 'axios';<-- 放在文件顶部。例子:

axios.get('https://www.w3schools.com/xml/note.xml').then(resp => {
    console.log(resp.data);
});
Run Code Online (Sandbox Code Playgroud)


小智 10

步骤1

yarn add esm
Run Code Online (Sandbox Code Playgroud)

或者

npm i esm --save
Run Code Online (Sandbox Code Playgroud)

第2步

包.json

yarn add esm
Run Code Online (Sandbox Code Playgroud)

步骤3

nodemon --exec npm start
Run Code Online (Sandbox Code Playgroud)


Luc*_* C. 10

如果您使用ES6 JavaScript 导入:

  1. 安装cross-env
  2. 改为package.json"test": "jest""test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
  3. 更多内容package.json,添加这些:
    ...,
    "jest": {
        "transform": {}
    },
    "type": "module"
Run Code Online (Sandbox Code Playgroud)

解释:

cross-env允许更改环境变量而不更改 npm 命令。接下来,在文件package.json中更改 npm 命令以启用对Jest 的实验性 ES6 支持,并配置 Jest 来执行此操作。


小智 9

我遇到了同样的问题,以下已修复它(使用节点 12.13.1):

  • .js文件扩展名更改为.mjs
  • --experimental-modules在运行您的应用程序时添加标志。
  • 可选:添加"type": "module"您的package.json

更多信息:https : //nodejs.org/api/esm.html


Dav*_*d S 9

我发现这个答案的 2020 年更新有助于回答这个问题,并告诉你为什么这样做:

这是摘录:

自 Node.js v12(2019 年 4 月)起,默认启用对 ES 模块的支持,自 Node.js v15(2020 年 10 月)起,它变得稳定(请参阅此处)。文件(包括 Node.js 模块)必须以 .mjs 结尾,或者最近的 package.json 文件必须包含“type”:“module”。Node.js 文档包含大量信息,还涉及 CommonJS 和 ES 模块之间的互操作性。

  • 我发现这个答案是对OP最清晰的解释。只是,假设我正在编写一个应用程序,而不是一个模块,_“不能在模块外部使用 import 语句”_ 是否意味着我无法使用 `import` 语句导入任何内容,因为我在模块外部,对吧?这仍然令人困惑。对于“包含节点模块的文件必须以 .mjs 结尾,或者最近的 package.json 文件必须包含“type”:“module”。”_,我正在编写一个应用程序,而不是一个模块,为什么我需要命名我的带有 mjs 的应用程序或将我的包设置为模块? (3认同)

小智 8

首先我们将安装@babel/cli, @babel/core and @babel/preset-env.

$ npm install --save-dev @babel/cli @babel/core @babel/preset-env
Run Code Online (Sandbox Code Playgroud)

然后我们将创建一个 .babelrc 文件来配置 babel。

$ touch .babelrc
Run Code Online (Sandbox Code Playgroud)

这将托管我们可能想要配置 babel 的任何选项。

{
  "presets": ["@babel/preset-env"]
}
Run Code Online (Sandbox Code Playgroud)

随着最近对 babel 的更改,您需要先转译ES6,然后 node 才能运行它。

因此,我们将在 package.json 中添加我们的第一个脚本 build。

"scripts": {
  "build": "babel index.js -d dist"
}
Run Code Online (Sandbox Code Playgroud)

然后我们将在 package.json 中添加我们的启动脚本。

"scripts": {
  "build": "babel index.js -d dist", // replace index.js with your filename
  "start": "npm run build && node dist/index.js"
}
Run Code Online (Sandbox Code Playgroud)

现在让我们启动我们的服务器。

$ npm start
Run Code Online (Sandbox Code Playgroud)


小智 7

我是 Node.js 新手,在修复 AWS Lambda 函数(使用 Node.js)时遇到了同样的问题。

我发现CommonJSES6 JavaScript之间的一些区别:

ES6:

  • 在package.json文件中添加“type”:“module”

  • 使用“导入”从 lib 中使用。

    示例:从 jwt-decode 导入 jwt_decode

  • Lambda 处理程序方法代码应该这样定义

    “exports.handler = 异步(事件)=> { }”

通用JS:

  • 不要在package.json文件中添加 "type":"module"

  • 使用“require”从 lib 中使用。

    示例:const jwt_decode = require("jwt-decode");

  • lambda 处理程序方法代码应如下定义:

    “导出常量处理程序 = 异步(事件)=> { }”


Roh*_*rte 6

尝试了所有方法,但没有任何效果

我从 git hub 得到了一份参考资料。

要在 nodejs 中使用类型脚本导入,我安装了下面的包。

1. npm i typescript

2. npm i ts-node
Run Code Online (Sandbox Code Playgroud)

不需要 type: module in package.json

例如

{
  "name": "my-app",
  "version": "0.0.1",
  "description": "",
  "scripts": {
   
  },
  "dependencies": {
    "knex": "^0.16.3",
    "pg": "^7.9.0",
    "ts-node": "^8.1.0",
    "typescript": "^3.3.4000"
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

就我而言。我认为问题出在标准node可执行文件中。node target.ts

我用它替换了它nodemon,令人惊讶的是它有效!

使用标准可执行文件(运行程序)的方式:

node target.ts
Run Code Online (Sandbox Code Playgroud)

使用nodemon可执行文件(运行程序)的方式:

nodemon target.ts
Run Code Online (Sandbox Code Playgroud)

不要忘记使用npm install nodemon;P安装 nodemon

注意:这对于开发来说非常有效。但是,对于运行时,您可以node使用编译后的.js文件执行!

问题是node不接受 TypeScript 文件。相反,ts-node可能是完美的替代品。

  • 也许nodemon将文件作为模块执行,因此本质上的错误消失了 (2认同)

小智 6

要使用导入,请执行以下操作之一。

  1. 将.js文件重命名为.mjs
  2. package.json文件中,添加{type:module}

  • 这无需在 **package.json** 中添加 `{type:module}` 即可工作 (2认同)

归档时间:

查看次数:

14001 次

最近记录:

5 年,11 月 前