我有一个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",

当前回答

如果有人在使用TypeScript时遇到了这个问题,对我来说,解决它的关键是改变

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

to

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

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

其他回答

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

例如,

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

Or

在babel.config.js

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

JavaScript模块文件的mime类型错误

该问题的常见根源是“模块”类型JavaScript文件的mime类型不能被处理或交付这些文件的服务器、客户端或ECMAScript引擎识别为“模块”类型。

The problem is the developers of Module JavaScript files incorrectly associated Modules with a new ".mjs" (.js) extension, but then assigned it a MIME-type server type of "text/javascript". This means both .js and .mjs types are the same. In fact the new type for .js JavaScript files has also changed to "application/javascript", further confusing the issue. So Module JavaScript files are not being recognized by any of these systems, regardless of Node.js or Babel file processing systems in development.

主要的问题是,大多数服务器或客户端(现代HTML5浏览器)还不知道这种新的JavaScript“模块”子类型。换句话说,除了JavaScript类型,他们没有办法知道Module文件类型到底是什么!

你得到了你发布的响应,JavaScript引擎说它需要知道这个文件是否是Module类型的JavaScript文件。

The only solution, for server or client, is to change your server or browser to deliver a new Mime-type that trigger ES6 support of Module files, which have an .mjs extension. Right now, the only way to do that is to either create a HTTP content-type on the server of "module" for any file with a .mjs extension and change your file extension on module JavaScript files to ".mjs", or have an HTML script tag with type="module" added to any external <script> element you use that downloads your external .js JavaScript module file.

一旦你欺骗浏览器或JavaScript引擎接受新的Module文件类型,它们就会开始在你使用的JS引擎或Node.js系统中进行脚本杂技表演。

首先,我们将安装 @babel/cli、@babel/core 和 @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

我也有同样的问题,下面已经修复了它(使用Node.js 12.13.1):

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

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

我遇到了同样的问题,而且更糟糕:我同时需要“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有一些关于导入的很好的文档