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

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

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

SyntaxError: Cannot use import statement outside a module

首先,我试图说服TPTB*这是一个模块(没有成功)。所以我把“import”改成了“require”,这就成功了。

但现在我在其他文件中有大约24个“导入”给我同样的错误。

*我敢肯定我问题的根源是我甚至不知道抱怨的是什么。我有点假设它是巴别塔7(因为我来自巴别塔6,我不得不改变预设),但我不是100%确定。

我发现的大多数解决方案似乎并不适用于直节点。比如这个:

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

说它是通过添加“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",

当前回答

对于那些和我一样在阅读答案时感到困惑的人,在你的包裹里。Json文件,添加 “类型”:“模块” 在上层如下图所示:

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

其他回答

我在一个刚刚起步的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'],
};

我不完全明白为什么这是可行的,但我是从权威来源复制的,所以我很高兴坚持下去。

节点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

谁试过从"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"来打包的人。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。

从'axios'导入axios;<——置于文件顶部。 例子:

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

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

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

一些较新的ES6模块只能使用导入。 一些CommonJS使用require。

以下是对我有效的方法:

把你的js文件转换成.mjs,就像其他答案中建议的那样 "require"在ES6模块中没有定义,所以你可以这样定义它: 从模块导入{createRequire} const require = createRequire(import.meta.url); 现在'require'可以用在通常的情况下。 对于ES6模块使用import,对于CommonJS使用require。

一些有用的链接:Node.js自己的文档。import和require的区别。Mozilla有一些关于导入的很好的文档

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

使用Node.js require vs. ES6导入/导出

以下是节选:

“更新2020

自Node v12以来,默认情况下启用了对ES模块的支持,但在撰写本文时仍处于试验阶段。包含节点模块的文件必须以.mjs或最近的包结尾。Json文件必须包含“type”:“module”。Node文档有更多的信息,也包括CommonJS和ES模块之间的互操作。”

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

node filename.ts

而不是

node filename.js

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