ChatGPT解决这个技术问题 Extra ChatGPT

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

我有一个 ApolloServer 项目给我带来了麻烦,所以我想我可能会更新它并在使用最新的 Babel 时遇到问题。我的“index.js”是:

require('dotenv').config()
import {startServer} from './server'
startServer()

当我运行它时,我得到了错误

SyntaxError: Cannot use import statement outside a module

首先,我试图说服 TPTB* 这是一个模块(没有成功)。所以我将“import”更改为“require”,这很有效。

但是现在我在其他文件中有大约两打“导入”,给了我同样的错误。

*我确定我的问题的根源是我什至不确定是什么在抱怨这个问题。我有点假设它是 Babel 7(因为我来自 Babel 6,我不得不更改预设)但我不是 100% 确定。

我发现的大多数解决方案似乎都不适用于直接 Node.js。就像这里的这个:

ES6 module Import giving "Uncaught SyntaxError: Unexpected identifier"

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

"presets": ["es2015", "stage-2"],
"plugins": []

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

以下是我开始使用的依赖项:

"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",
你好,现在遇到同样的问题。您还可以分享您的依赖项吗?更新前后甚至可能存在差异。我可以检查我的,看看我们是否能找到可能导致问题的类似包。
我刚刚用“requires”替换了所有“imports”,现在一切都很好。愚蠢,但现在不值得努力弄清楚。不过,我将使用依赖项更新原始版本。如果你有任何线索,我会对照我的原始代码检查它们。
CommonJS 语法(require 和 module.exports)是 node 的原始格式,webpack 也支持它,但是 ES6 模块语法(export,import)是更新的方式,现在 node 和 webpack 支持它。我读到 node 现在支持导入,但是很多教程都显示需要纯 node 的东西,所以最好使用 node 的语法。
嗯,有趣的是,该预设只设置了 {allowJs: true} 设置。同样,我也(已经)添加到 TS compilerOptions。也许你想看看这个。编辑:天哪,如果你真的使用 TS? ... 什么配置地狱。
"type":"module" 没有解决我的问题,而且有一百多个 importsrequire 的语法与 imports 不同,不是一个简单的替换。你能举例说明 imports 是如何被 requires 替换的吗?

P
Peter Mortensen

验证您是否安装了最新版本的 Node.js(或至少 13.2.0+)。然后执行以下操作之一,如 described in the documentation

选项1

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

// package.json
{
  "type": "module"
}

选项 2

使用 .mjs 扩展名显式命名文件。所有其他文件,例如 .js 将被解释为 CommonJS,如果 type 未在 package.json 中定义,则这是默认值。


如果我使用这个,然后更改路径以包含所需文件的“js”,然后更改所需文件中导出语句的格式,然后将我从“import”更改的所有“require”语句取出 - 因为现在“要求”是未知的——这会起作用,所以我会接受这个答案。
如果问题出在 node_modules/ 下,这不是一个真正的选择,对吗?在这种情况下如何解决的任何想法?
或使用通天塔! ` module.exports = { 预设:['@babel/preset-env'], }; `
@Cocuba 答案是正确的,应该是公认的答案,因为它实际上可以转换。
如果您正在运行 .ts 个文件,则此解决方案不起作用。如果您可以简单地使用 nodemon 而不是 node 添加它,根据下面的这个答案 stackoverflow.com/a/65058291/11664580,它有望为人们节省我花了半天时间胡闹的时间。或者,根据 stackoverflow.com/a/61947868/11664580,安装 ts-node 似乎是一种解决方案
P
Peter Mortensen

如果有人遇到TypeScript这个问题,那么为我解决这个问题的关键是改变

    "target": "esnext",
    "module": "esnext",

    "target": "esnext",
    "module": "commonjs",

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


如果您使用的是 babel-node,那么您还需要使用 --extensions 选项,例如 babel-node --extensions \".ts,.tsx\" src/index
是的,这是在尝试“type”时做到的:“module”突然说“require is undefined”。
该死的,它让我免于很多麻烦。我在印象中犯了同样的错误,即 esnext 是最好的
你的答案有效。你能解释一下为什么我们要这样调整吗? @Dr-Bracket 谢谢
简单并为我解决了这个问题。
B
Brian Burns

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

{
  "name": "my-app",
  "version": "0.0.0",
  "type": "module",
  "scripts": { ...
  },
  ...
}

tx,但是你知道我在哪里可以找到 package.json 吗?我正在使用netbeans。我还在我的 macbook 上搜索了 package.json,但我看到了很多 package.json 文件。有小费吗?
嗨,Alex,在 Java 项目中工作已经有一段时间了,但我希望此链接可以为您提供有关在哪里找到 package.json 文件的线索:stackoverflow.com/questions/41513559/…
L
Liam

根据the official documentation

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

要让 Node.js 将您的文件视为 ES 模块,您需要 (Enabling):

将 "type": "module" 添加到 package.json

在 Node.js 调用中添加“--experimental-modules”标志


2020 年更新:不再需要 --experimental-modules
不是说这个答案是错误的,我看过相同的文档。但我看不出在 CommonJS 中使用 import() 访问 es6 模块的建议有什么用。它是异步的,因此不能用于在文件级别导入任何内容。至少可以说,这使得尝试从 CommonJS 访问 es6 模块很痛苦。考虑到主要的单元测试框架 Jasmine Jest 等根本不能很好地处理这个问题,这让我认为,除非有更好的互操作支持,否则整个 Node es6 的情况对我来说似乎是半生不熟,但我很想被证明是错误的。
P
Peter Mortensen

我遇到了同样的问题,更糟糕的是:我需要“import”和“require”

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

这对我有用:

按照其他答案中的建议将您的 js 文件转换为 .mjs ES6 模块未定义“require”,因此您可以这样定义: import { createRequire } from 'module' const require = createRequire(import.meta.url) ;现在'require'可以以通常的方式使用。对 ES6 模块使用 import,对 CommonJS 使用 require。

一些有用的链接:Node.js's own documentationdifference between import and requireMozilla has some nice documentation about import


P
Peter Mortensen

我遇到了同样的问题,以下解决了它(使用 Node.js 12.13.1):

将 .js 文件扩展名更改为 .mjs

在运行您的应用程序时添加 --experimental-modules 标志。

可选:在你的 package.json 中添加 "type": "module"

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


A
Alisson Reinaldo Silva

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

我从 GitHub 获得了一份参考资料。

要将 TypeScript 导入与 Node.js 一起使用,我安装了以下软件包。

1. npm i typescript --save-dev

2. npm i ts-node --save-dev

不需要 type: 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"
  }
}

我遇到过同样的问题。作为替代方案,只需使用 nodemon 而不是 node 运行 package.json 脚本也可以。无需安装另一个包(假设您已经在运行 nodemon)。信用:stackoverflow.com/a/65058291/11664580
是的,这救了我!谢谢!
他们应该去 devDependencies 代替。
P
Peter Mortensen

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

npm install --save-dev @babel/cli @babel/core @babel/preset-env

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

touch .babelrc

这将承载我们可能想要配置 Babel 的任何选项:

{
  "presets": ["@babel/preset-env"]
}

随着最近对 Babel 的更改,您将需要在 Node.js 运行之前编译 ES6。

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

"scripts": {
  "build": "babel index.js -d dist"
}

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

"scripts": {
  "build": "babel index.js -d dist", // replace index.js with your filename
  "start": "npm run build && node dist/index.js"
}

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

npm start

A
Abhishek Kumar

步骤1

yarn add esm

或者

npm i esm --save

第2步

包.json

  "scripts": {
    "start": "node -r esm src/index.js",
  }

第 3 步

nodemon --exec npm start

当您无法将 "type": "module" 添加到 package.json 文件时,+1 esm 似乎是最简单的解决方案。
A
Adrian

Node 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

谁尝试过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  

并且谁尝试过 "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"
}

我能够毫无问题地切换到 axios。

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

axios.get('https://www.w3schools.com/xml/note.xml').then(resp => {

    console.log(resp.data);
});

D
David S

我发现此链接中答案的 2020 年更新有助于回答此问题并告诉您为什么这样做:

Using Node.js require vs. ES6 import/export

这是一段摘录:

“2020年更新

从 Node v12 开始,默认启用对 ES 模块的支持,但在撰写本文时它仍处于试验阶段。包含节点模块的文件必须以 .mjs 结尾,或者最近的 package.json 文件必须包含“type”:“module”。 Node 文档有更多信息,还有关于 CommonJS 和 ES 模块之间的互操作。”


我发现这个答案是对 OP 最清楚的解释。只是,假设我正在编写一个应用程序,而不是一个模块,"Cannot use import statement outside a module" 是否意味着我不能使用 import 语句导入任何内容,因为我在模块之外,对吧?这仍然令人困惑。对于“包含节点模块的文件必须以.mjs 结尾或最近的package.json 文件必须包含“type”:“module”。”,我正在编写一个应用程序,而不是一个模块,为什么我需要用 mjs 命名我的应用程序或将我的包设置为模块?
@xpt 嘿。因此,您无法比较应用程序和模块。我认为您可能会根据节点模块来考虑它,这似乎是您程序中的一个程序。这并不是真正的模块。让我澄清一下什么是模块,我认为这将解决您的困惑:
@xpt 这样想,您正在编写一个应用程序并处理一个名为 main-file.js 的文件。您想从另一个名为 some-other-file.js 的文件中导入一个函数。 some-other-file.js 非常大,您不需要整个文件。您只需要文件中的函数。现在,如果 some-other-file.js 和 main-file.js 是模块 (.mjs),您可以“导入”您想要的功能,例如从 './some-other-file' 导入 someFunction。总而言之,模块是一个js文件,可以通过其功能分隔,因此它可以导出与整个文件相对的特定功能。那有意义吗?
感谢大卫的解释。所以我理解 some-other-file.js 是模块,它可以导出与整个文件相反的特定功能。但是,main-file.js 也是一个模块吗?不,这只是我的应用程序的主要部分。 “不能在模块外使用 import 语句”规则是否适用于 main-file.js(因为它不是模块)?
无论如何,我想我最好还是问一个新问题 -- stackoverflow.com/questions/71240736
V
Vidya Sagar H J

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

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


这无需在 package.json 中添加 {type:module} 即可
P
Peter Mortensen

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

我用 nodemon 替换了它,令人惊讶的是它起作用了!

使用标准可执行文件(runner)的方式:

node target.ts

使用nodemon可执行文件(runner)的方式:

nodemon target.ts

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

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


也许 nodemon 将文件作为模块执行,因此本质上错误消失了
P
Peter Mortensen

运行命令时也会出现此错误

node filename.ts

并不是

node filename.js

简单地说,使用 node 命令,我们必须运行 JavaScript 文件 (filename.js) 而不是 TypeScript 文件,除非我们使用像 ts-node


D
Daniel

如果你想使用 BABEL,我有一个简单的解决方案!

请记住,这是针对 nodejs 的示例:就像 expressJS 服务器一样!

如果你打算使用 react 或其他框架,请查看 babel 文档!

首先,安装(不要安装只会破坏您的项目的不必要的东西!)

npm install --save-dev @babel/core @babel/node

只需 2 WAO

然后在你的 repo 中配置你的 babel 文件!

https://i.stack.imgur.com/4SsC9.png

文件名:

babel.config.json

{
    "presets": ["@babel/preset-env"]
}

如果您不想使用 babel 文件,请使用:

在您的控制台中运行,script.js 是您的入口点!

npx babel-node --presets @babel/preset-env -- script.js

https://i.stack.imgur.com/vCXPq.png

完整信息在这里; https://babeljs.io/docs/en/babel-node


F
Faisal Amin

在 package.json 中写 { "type": "module" }

它解决了我的问题,我遇到了同样的问题


上面给出了相同的答案并得到了很多赞成。
A
Ahmed Adewale

我在运行迁移时遇到了这个问题

它的 es5 vs es6 问题

这是我解决它的方法

我跑

npm install @babel/register

并添加

require("@babel/register")

在我的 .sequelizerc 文件的顶部

并继续运行我的续集迁移。这适用于除sequelize之外的其他事情

babel 进行编译


P
Peter Mortensen

只需添加 --presets '@babel/preset-env'

例如,

babel-node --trace-deprecation --presets '@babel/preset-env' ./yourscript.js

或者

babel.config.js

module.exports = {
  presets: ['@babel/preset-env'],
};

P
Peter Mortensen

为了使您的导入工作并避免其他问题,例如模块在 Node.js 中不起作用,请注意:

使用 ES6 模块,您还不能导入目录。您的导入应如下所示:

import fs from './../node_modules/file-system/file-system.js'

L
Luca C.

如果您使用 ES6 JS 导入:

在 package.json 中安装 cross-env 将 package.json 中的“test”:“jest”更改为“test”:“cross-env NODE_OPTIONS=--experimental-vm-modules jest”,添加以下内容:

    ...,
    "jest": {
        "transform": {}
    },
    "type": "module"

解释:cross-env 允许在不更改 npm 命令的情况下更改环境变量,接下来在 package.json 中更改 npm 命令以启用对 jest 的实验性 ES6 支持,并配置 jest 来执行此操作


P
Peter Mortensen

我的解决方案是在运行 nodemon 时包含 babel-node 路径,如下所示:

nodemon node_modules/.bin/babel-node index.js

您可以将 package.json 脚本添加为:

debug: nodemon node_modules/.bin/babel-node index.js

注意:我的入口文件是 index.js。将其替换为您的入口文件(许多有 app.js/server.js)。


P
Peter Mortensen

刚开始使用 Babel 的时候也遇到了同样的问题……不过后来我有了解决办法……到现在都没有问题了……目前,Node.js v12.14.1, "@babel /node": "^7.8.4",我使用 babel-node 和 nodemon 执行(Node.js 也可以..) package.json: "start": "nodemon --exec babel-node server.js "debug": "babel-node debug server.js"!! 注意:server.js是我的入口文件,你可以使用你的launch.json。调试的时候还需要配置你的launch.json文件runtimeExecutable": "${workspaceRoot}/node_modules/.bin/babel-node"!!注意:在配置中加上runtimeExecutable。当然,有了babel-node,你通常还需要编辑另外一个文件,比如babel。 config.js/.babelrc 文件


P
Peter Mortensen

如果您正在为 Node.js 版本 12 运行 nodemon,请使用此命令。

server.jspackage.json 文件中的“主”,将其替换为 package.json 文件中的相关文件:

nodemon --experimental-modules server.js

此标志似乎已从最新版本中删除
P
Peter Mortensen

我最近有这个问题。对我有用的修复是将其添加到插件部分的文件 babel.config.json 中:

["@babel/plugin-transform-modules-commonjs", {
    "allowTopLevelThis": true,
    "loose": true,
    "lazy": true
  }],

我有一些带有 // 的导入模块和错误“不能在模块外使用导入”。


n
ncutixavier

如果您使用的是节点,则应参考此document。只需在您的节点应用程序中设置 babel,它就可以工作并且对我有用。

npm install --save-dev @babel/cli @babel/core @babel/preset-env

这对我不起作用
P
Pieterjan

手动升级后,我的 NX 工作区 中出现此错误。每个 jest.config.js 中的以下更改修复了它:

transform: {
  '^.+\\.(ts|js|html)$': 'jest-preset-angular',
},

transform: {
  '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular',
},

E
Ekansh Saxena

对于即使在 package.json 文件中添加 "type": "module" 后由于 Netlify 函数中的此错误而来到此线程的人,请更新您的 netlify.toml 以使用“esbuild”。由于 esbuild 支持 ES6,它可以工作。

[functions]
  node_bundler = "esbuild"

参考:https://docs.netlify.com/functions/build-with-javascript/#automated-dependency-bundling


D
DariusV

https://i.stack.imgur.com/omFRZ.png

请注意,您必须安装 babel 和 babel register


h
halfer

我在一个初出茅庐的 Express API 项目中遇到了这个问题。

src/server/server.js 中的违规服务器代码:

import express from 'express';
import {initialDonationItems, initialExpenditureItems} from "./DemoData";

const server = express();

server.get('/api/expenditures', (req, res) => {
  res.type('json');
  res.send(initialExpenditureItems);
});

server.get('/api/donations', (req, res) => {
  res.type('json');
  res.send(initialDonationItems);
});

server.listen(4242, () => console.log('Server is running...'));

这是我的依赖项:

{
  "name": "contributor-api",
  "version": "0.0.1",
  "description": "A Node backend to provide storage services",
  "scripts": {
    "dev-server": "nodemon --exec babel-node src/server/server.js --ignore dist/",
    "test": "jest tests"
  },
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.9.6",
    "@babel/node": "^7.8.7",
    "babel-loader": "^8.1.0",
    "express": "^4.17.1",
    "mysql2": "^2.1.0",
    "sequelize": "^5.21.7",
    "sequelize-cli": "^5.5.1"
  },
  "devDependencies": {
    "jest": "^25.5.4",
    "nodemon": "^2.0.3"
  }
}

这是引发错误的跑步者:

nodemon --exec babel-node src/server/server.js --ignore dist

这令人沮丧,因为我有一个类似的 Express 项目运行良好。

解决方案是首先添加此依赖项:

npm install @babel/preset-env

然后在项目根目录中使用 babel.config.js 将其连接:

module.exports = {
  presets: ['@babel/preset-env'],
};

我不完全理解为什么会这样,但我从 an authoritative source 复制了它,所以我很乐意坚持下去。


是的,我的问题是代码有一堆预设,我永远无法完全平衡我想要的东西和我不想要的东西/破坏的东西。
我整天都在努力解决令人困惑的 JS 崩溃 @user3810626 - 我怀疑我的问题是我对语言和生态系统还很陌生,我需要暂时搁置一些学习来让工作正常进行。到达那里... :-)
祝你好运!外面是丛林! (我的意思是,从字面上看,JS 生态系统是一片丛林……)
@user3810626 nodejs 开发人员不再知道事情是如何工作的。他们只是不断尝试 Stack Overflow 个解决方案,直到出现问题
这在某些社区似乎比其他社区更真实。
P
PositiveGuy

取出 "module": "esnext" 并确保其中包含 "moduleResolution": "node",该特定组合为我完成了