SyntaxError:无法在模块外部使用导入语句

时间:2019-10-14 21:17:18

标签: javascript node.js babeljs apollo-server

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

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

当我运行它时,出现错误“ SyntaxError:无法在模块外部使用import语句”。首先,我尝试做一些事情以说服TPTB *,这是一个模块(没有成功)。因此,我将“导入”更改为“需要”,并且可行。

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

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

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

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",

22 个答案:

答案 0 :(得分:23)

如果有人遇到 Typescript 的问题,那么为我解决此问题的关键就在改变

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

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

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

答案 1 :(得分:22)

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

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

答案 2 :(得分:10)

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

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

这对我有用:

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

  2. ES6模块未定义“ require”,因此可以这样定义:

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

    现在“ require”可以按常规方式使用。

  3. 将导入用于ES6模块,并需要commonJS。

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

答案 3 :(得分:9)

根据官方文档(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):

  • 在package.json中添加“类型”:“模块”
  • 在节点调用中添加“ --experimental-modules”标志

答案 4 :(得分:4)

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

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

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

答案 5 :(得分:4)

首先,我们将安装@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的最新更改,您需要先转换 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

答案 6 :(得分:1)

更新(节点13.2.0 +)

验证您已安装最新版本的Node。不再需要--experimental-modules标志。只需执行以下操作之一

  • "type": "module"添加到最近的父package.json。这样,所有.js.mjs文件都被解释为ES模块。您可以使用.cjs扩展名将单个文件解释为CommonJS。

OR

  • 使用扩展名.mjs明确命名文件。所有其他文件,例如.js将被解释为CommonJS,如果type中未定义package.json,这是默认设置。

答案 7 :(得分:1)

尝试了所有方法,但无济于事

我从git hub获得了一个参考。

要在Node.js中使用类型脚本导入,我在软件包下面安装了

1. npm i typescript

2. npm i ts-node

不需要类型:package.json中的模块

E:g

{
  "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"
  }
}

答案 8 :(得分:0)

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

Using Node.js require vs. ES6 import/export

这里是摘录:

"2020 年更新

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

答案 9 :(得分:0)

在 package.json 中写入 { “类型”:“模块” }

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

答案 10 :(得分:0)

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

其es5 vs es6问题

这是我解决的方式

我跑步

npm install @babel/register

并添加

require("@babel/register")

位于我的.sequelizerc文件顶部

继续运行我的续集迁移。 除了续集,这也适用于其他事物

babel进行转堆

答案 11 :(得分:0)

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

我用nodemon取代了它,但令人惊讶的是它起作用了!

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

node target.ts

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

nodemon target.ts

不要忘记使用npm install nodemon; P

安装nodemon

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

答案 12 :(得分:0)

我只是想添加一些东西来使您的导入工作并避免其他问题,例如模块在node js中不起作用。请注意

使用ES6模块,您尚无法导入目录。您的导入应如下所示:

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

答案 13 :(得分:0)

最近有问题。对我来说有效的解决方案是将其添加到插件部分的babel.config.json中

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

我使用/ / 导入了一些模块,并且出现错误“无法在模块外部使用导入”。

答案 14 :(得分:0)

如果您正在运行节点版本12的节点,请使用此命令。 server.js package.json文件中的“主”文件,将其替换为package.json文件中的相关文件

nodemon --experimental-modules server.js

答案 15 :(得分:0)

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

node filename.ts

不是

node filename.js

简单地说,除非使用的是 ts-node

之类的程序,否则必须使用node命令运行JavaScript文件(filename.js)而不是TypeScript文件。

答案 16 :(得分:-1)

第1步

yarn add esm

npm i esm --save

第2步

package.json

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

第3步

nodemon --exec npm start

答案 17 :(得分:-1)

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

例如

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

OR

babel.config.js

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

答案 18 :(得分:-1)

  1. 当我开始使用babel时,我遇到了同样的问题...但是后来,我 有解决方案...到目前为止我再也没有问题了... 当前,节点v12.14.1,“ @ babel / node”:“ ^ 7.8.4”,我使用babel-node 和nodemon来执行(node也很好。)
  2. package.json:“开始”:“ nodemon --exec babel-node server.js”“调试”:“ babel-node调试server.js” !!注:server.js是我的条目 文件,您可以使用您的文件。
  3. launch.json 调试时,还需要配置launch.json文件“ runtimeExecutable”: “ $ {workspaceRoot} /node_modules/.bin/babel-node” !!注意:加 runtimeExecutable到配置中。
  4. 当然,对于babel-node,您通常还需要编辑另一个 文件,例如babel.config.js / .babelrc文件

答案 19 :(得分:-2)

我在一个新兴的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复制了它,因此我很乐意坚持。

答案 20 :(得分:-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)替换。

答案 21 :(得分:-3)

简单,只需将其更改为:const uuidv1 = require('uuid'); 它会正常工作。