393

我有一个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 模块导入给出“未捕获的语法错误:意外的标识符”

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

29 回答 29

467

验证您是否安装了最新版本的 Node.js(或至少 13.2.0+)。然后按照文档中的说明执行以下操作之一:

选项1

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

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

选项 2

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

于 2019-12-18T20:43:35.690 回答
120

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

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

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

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

于 2020-07-10T15:03:44.703 回答
71

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

{
  "name": "my-app",
  "version": "0.0.0",
  "type": "module",
  "scripts": { ...
  },
  ...
}
于 2020-06-12T09:03:02.193 回答
54

根据官方文档

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

要使 Node.js 将您的文件视为 ES 模块,您需要(启用):

  • 将 "type": "module" 添加到 package.json
  • 在 Node.js 调用中添加“--experimental-modules”标志
于 2019-11-21T14:13:28.287 回答
32

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

  1. 一些较新的 ES6 模块仅适用于import
  2. 一些CommonJSrequire一起工作。

这对我有用:

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

  2. "require" 没有用 ES6 模块定义,所以你可以这样定义:

    import { createRequire } from 'module'
    const require = createRequire(import.meta.url);
    

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

  3. 对 ES6 模块使用import ,对 CommonJS 使用require

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

于 2020-05-22T04:26:33.673 回答
13

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

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

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

于 2019-11-25T09:49:51.010 回答
10

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

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

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

1. npm i typescript

2. npm i ts-node

不需要 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"
  }
}
于 2020-11-04T11:51:51.903 回答
10

首先我们将安装@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
于 2020-08-19T11:50:02.257 回答
7

步骤1

yarn add esm

或者

npm i esm --save

第2步

包.json

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

第 3 步

nodemon --exec npm start
于 2020-07-31T06:22:48.203 回答
6

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

使用 Node.js 需要与 ES6 导入/导出

这是一段摘录:

" 2020 年更新

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

于 2021-07-21T20:41:55.313 回答
5

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);
});
于 2021-09-27T19:10:28.500 回答
4

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

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

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

node target.ts

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

nodemon target.ts

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

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

于 2020-11-29T08:30:53.733 回答
3

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

  1. 将.js文件重命名为.mjs
  2. package.json文件中,添加{type:module}
于 2022-02-02T16:01:26.280 回答
2

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

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

于 2021-02-21T06:49:34.980 回答
2

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

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

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

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

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

只需 2 WAO

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

快速服务器节点 js 和 babel 的示例

文件名:

babel.config.json

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


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

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

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

没有文件的示例 babel

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

于 2021-12-30T23:52:38.277 回答
2

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

node filename.ts

并不是

node filename.js

简而言之,除非我们使用像ts-nodenode这样的包,否则我们必须使用该命令运行 JavaScript 文件 ( filename.js ) 而不是 TypeScript 文件。

于 2020-09-15T04:06:48.350 回答
1

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

例如,

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

或者

babel.config.js

module.exports = {
  presets: ['@babel/preset-env'],
};
于 2020-06-18T14:08:28.903 回答
1

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

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

import fs from './../node_modules/file-system/file-system.js'
于 2020-10-27T13:59:03.443 回答
1

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

它的 es5 vs es6 问题

这是我解决它的方法

我跑

npm install @babel/register

并添加

require("@babel/register")

在我的 .sequelizerc 文件的顶部

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

babel 进行编译

于 2020-12-01T10:58:21.593 回答
0

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

npm install --save-dev @babel/cli @babel/core @babel/preset-env
于 2021-09-20T21:37:42.037 回答
0
  1. 刚开始使用 Babel 的时候也遇到了同样的问题……不过后来我有了解决办法……到现在都没有问题了……目前,Node.js v12.14.1, "@babel /node": "^7.8.4",我使用 babel-node 和 nodemon 执行(Node.js 也可以..)
  2. package.json: "start": "nodemon --exec babel-node server.js "debug": "babel-node debug server.js"!!注意:server.js是我的入口文件,你可以使用你的。
  3. 启动.json。调试的时候还需要配置你的launch.json文件“runtimeExecutable”:“${workspaceRoot}/node_modules/.bin/babel-node”!!注意:加上 runtimeExecutable 进入配置。
  4. 当然,使用 babel-node,您通常还需要和编辑另一个文件,例如babel.config.js/.babelrc文件
于 2020-02-12T16:48:58.460 回答
0

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

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

我有一些带有//的导入模块,并且错误“无法在模块外使用导入”。

于 2020-10-02T08:43:23.843 回答
0

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

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

transform: {
  '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular',
},
于 2021-12-30T13:35:02.157 回答
0

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

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

nodemon --experimental-modules server.js
于 2020-09-27T13:30:00.537 回答
-1

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

[functions]
  node_bundler = "esbuild"

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

于 2022-01-30T18:52:14.867 回答
-1

我有同样的问题,我在我的 Nodejs 应用程序中复制了 import 语句。require我通过使用而不是修复它import

于 2021-10-02T15:16:07.737 回答
-1

我在一个初出茅庐的 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然后在项目根目录中使用 a 连接它:

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

我不完全理解为什么会这样,但我从权威来源复制了它,所以我很高兴坚持下去。

于 2020-05-04T16:26:37.407 回答
-2

我的解决方案是在运行 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)。

于 2020-02-05T05:57:21.483 回答
-7

只需将其更改为:

const uuidv1 = require('uuid');

它会正常工作。

于 2020-06-21T16:12:11.473 回答