SyntaxError: Cannot use import statement outside a module

SyntaxError: Cannot use import statement outside a module

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

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

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

SyntaxError: Cannot use import statement outside a module

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

但现在我在其他文件中有大约两打“imports”给我同样的错误。

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

我发现的大多数解决方案似乎并不适用于纯 Node。喜欢这里的这个:

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

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

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

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

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

根据the official documentation

import statements are permitted only in ES modules. For similar functionality in CommonJS, see import().

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

  • 将“类型”:“模块”添加到 package.json
  • 在 Node.js 调用中添加“--experimental-modules”标志

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

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

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

确认您安装了最新版本的 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,如果 package.json.

中未定义 type,则这是默认设置

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

  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. launch.json。当你调试时,你还需要配置你的launch.json文件“runtimeExecutable”: “${workspaceRoot}/node_modules/.bin/babel-node”!!注:加上 运行时可执行到配置中。
  4. 当然,使用babel-node,你通常还需要编辑另一个文件,比如babel.config.js/.babelrc文件

我在刚刚起步的 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 复制了它,所以我很乐意坚持使用它。

我 运行 遇到了同样的问题,而且更糟:我需要“导入”和“要求”

  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's own documentation. difference between import and require. Mozilla has some nice documentation about import

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

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

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

例如,

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

babel.config.js

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

只需将其更改为:

const uuidv1 = require('uuid');

它将正常工作。

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

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

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

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

第 1 步

yarn add esm

npm i esm --save

第 2 步

package.json

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

第 3 步

nodemon --exec npm start

首先我们将安装 @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,然后 Node.js 才能 运行 它。

因此,我们将在文件 package.json.

中添加我们的第一个脚本构建
"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 filename.ts

而不是

node filename.js

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

这样的包

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

server.jspackage.json 文件中的“主要”,将其替换为 [=22= 中的相关文件] 文件:

nodemon --experimental-modules server.js

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

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

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

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

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

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

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

我从 GitHub 那里得到了一个参考。

为了通过 Node.js 使用 TypeScript 导入,我安装了以下包。

1. npm i typescript --save-dev

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

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

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

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

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

node target.ts

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

nodemon target.ts

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

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

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

它的 es5 与 es6 问题

我是这样解决的

我运行

npm install @babel/register

并添加

require("@babel/register")

在我的 .sequelizerc 文件的顶部

然后继续 运行 我的续集迁移。 这适用于sequelize

以外的其他事情

babel 进行转译

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

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

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

摘录如下:

"2020 年更新

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

如果你正在使用node,你应该参考这个document。只需在您的节点应用程序中设置 babel 它就可以工作并且对我有用。

npm install --save-dev @babel/cli @babel/core @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

谁试过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);
});

我遇到了同样的问题,我在我的 Nodejs 应用程序中复制了导入语句。我使用 require 而不是 import.

修复了它

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

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

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

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

记住这是针对 nodejs 的例子:就像一个 expressJS 服务器!

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

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

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

Just 2 WAO

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

文件名:

babel.config.json

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


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

Run in your console, and script.js is your entry point!

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

the full information is here; https://babeljs.io/docs/en/babel-node

对于即使在 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

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

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

取出 "module": "esnext" 并确保 "moduleResolution": "node" 在里面,那个特定的组合为我做了

当我将 sequelize 迁移与 npx sequelize db:migrate 一起使用时,我遇到了这个错误,所以我的解决方案是将下一行 require('@babel/register'); 添加到 .sequelizerc 文件中,如下图所示

注意你必须安装 babel 和 babel register