繁体   English   中英

SyntaxError: 不能在模块外使用 import 语句

[英]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 ”并且这有效。

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

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

我发现的大多数解决方案似乎并不适用于直接 Node。 就像这里的这个:

ES6 模块导入给出“Uncaught SyntaxError: Unexpected identifier”

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

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

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

选项1

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

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

选项 2

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

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

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

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

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

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

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

根据官方文档

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

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

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

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

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

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

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

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

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

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

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

首先,我们将安装@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

步骤1

yarn add esm

或者

npm i esm --save

第2步

package.json

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

第 3 步

nodemon --exec npm start

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

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

这是一段摘录:

" 2020 年更新

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

节点 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);
});

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

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

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

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

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

node target.ts

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

nodemon target.ts

不要忘记使用npm install nodemon ;P

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

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

node filename.ts

并不是

node filename.js

简而言之,使用node命令,我们必须运行 JavaScript 文件 ( filename.js ) 而不是 TypeScript 文件,除非我们使用ZEFE90A8E604A7C840E88ZD03A67F6B7D文件。

如果你想使用 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

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

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

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

例如,

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

或者

babel.config.js

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

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

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

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

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

它的 es5 vs es6 问题

这是我解决它的方法

我跑

npm install @babel/register

并添加

require("@babel/register")

在 my.sequelizerc 文件的顶部

和 go 提前运行我的续集迁移。 这适用于除sequelize之外的其他事情

babel 进行编译

如果您使用 ES6 JS 导入:

  1. 安装cross-env
  2. package.json "test": "jest"更改为"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
  3. 更多在package.json中,添加这些:
    ...,
    "jest": {
        "transform": {}
    },
    "type": "module"

explanation: cross-env allows to change environment variables without changing npm command, next in package.json you change your npm command to enable experimental ES6 support for jest, and configure jest to do it

当我根据 VSCode 的建议将const {app, BrowserWindow} = require('electron')更改为import { app, BrowserWindow } from 'electron'时遇到了这个问题。 之后它开始给我错误。

当我把它改回原来的它开始工作正常。 对不起,我不知道它为什么起作用。

我的解决方案是在运行 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. 发射.json 调试的时候还需要配置你的launch.json文件“runtimeExecutable”:“${workspaceRoot}/node_modules/.bin/babel-node”:。 注意:加上 runtimeExecutable 进入配置。
  4. 当然,使用 babel-node,您通常还需要和编辑另一个文件,例如babel.config.js/.babelrc文件

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

server.jspackage.json文件中的相关文件:

nodemon --experimental-modules server.js

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

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

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

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

npm install --save-dev @babel/cli @babel/core @babel/preset-env

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

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

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

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

[functions]
  node_bundler = "esbuild"

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

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

请注意,您必须安装 babel 和 babel register

我是 NodeJS 的新手,我在修复它时遇到了 AWS Lambda function(使用 NodeJS)同样的问题

我发现了 common-js 和 ES6 javascript 之间的一些区别:

ES6:

  • 在 package.json 文件中添加“类型”:“模块”

  • 使用“导入”从库中使用。

    例如:从 jwt-decode 导入 jwt_decode

  • Lambda 处理程序方法代码应该这样定义

    “exports.handler = 异步(事件)=> { }”

常见的js:

  • 不要在 package.json 文件中添加“类型”:“模块”

  • 使用 "require" 从 lib 中使用。

    例如: const jwt_decode = require("jwt-decode");

  • Lambda 处理程序方法代码应该这样定义

    “导出常量处理程序=异步(事件)=> {}”

JavaScript 模块文件的错误 MIME 类型

问题的常见来源是“模块”类型 JavaScript 文件的 MIME 类型未被服务器、客户端或处理或传送这些文件的 ECMAScript 引擎识别为“模块”类型。

问题是模块 JavaScript 文件的开发人员错误地将模块与新的“.mjs”(.js) 扩展名相关联,但随后为其分配了“text/javascript”的 MIME 类型服务器类型。 这意味着 .js 和 .mjs 类型是相同的。 事实上,新类型 for.js JavaScript 文件也更改为“application/javascript”,进一步混淆了问题。 因此,无论 Node.js 还是开发中的 Babel 文件处理系统,模块 JavaScript 文件都无法被任何这些系统识别。

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

所以,你得到了你发布的响应,JavaScript 引擎说它需要知道文件是否是 JavaScript 文件的模块类型。

对于服务器或客户端,唯一的解决方案是change your server or browser to deliver a new Mime-type that trigger ES6 support of Module files ,这些文件具有.mjs扩展名。 现在,唯一的方法是在“ module ”的服务器上为任何具有.mjs扩展名的文件创建一个HTTP content-type ,并将模块 JavaScript 文件的文件扩展名更改为“.mjs”,或者让一个带有type="module"的 HTML 脚本标签添加到您使用的任何外部<script>元素,用于下载您的外部.js JavaScript 模块文件。

一旦您欺骗浏览器或 JavaScript 引擎接受新的 Module 文件类型,它们将开始在您使用的 JS 引擎或 Node.js 系统中执行脚本马戏团技巧。

前:

从'./route/student'导入标准

后:

从 './route/student.js' 导入标准

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

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

取出"module": "esnext"并确保其中有“moduleResolution "moduleResolution": "node" ,那个特定的组合为我做了

文档令人困惑。 我使用 node.js 在我的计算机中执行一些本地任务。

假设我的旧脚本是test.js
在里面,如果我想使用

import something from "./mylocalECMAmodule";

会抛出这样的错误

(node:16012) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
SyntaxError: Cannot use import statement outside a module
...

这不是模块错误,而是 node.js 错误,禁止加载“模块”之外的任何内容。

要解决此问题,只需将旧脚本test.js重命名为test.mjs

就这样。

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

只需将其更改为:

const uuidv1 = require('uuid');

它会正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM