ChatGPT解决这个技术问题 Extra ChatGPT

Node.js - SyntaxError:意外的令牌导入

我不明白出了什么问题。节点 v5.6.0 NPM v3.10.6

编码:

function (exports, require, module, __filename, __dirname) {
    import express from 'express'
};

错误:

SyntaxError: Unexpected token import
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:387:25)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:140:18)
    at node.js:1001:3
使用像 Babel 这样的转译器在 Nodejs 中使用 import,因为它在 nodejs 中不受本机支持。导入的最佳替代方案是 require 所以去吧。
结帐支持 import () nodejs v16 - nodejs.org/api/packages.html
@BHUVNESHKUMAR:您的陈述在 2022 年仍然正确吗?

T
Tanckom

节点 13+Node 13 开始,您可以使用 .mjs 扩展,或在 package.json 中设置 {"type": "module"}。您不需要使用 --experimental-modules 标志。 Modules is now marked as stable in node.js

节点 12Node 12 开始,您可以使用 .mjs 扩展,或在 package.json 中设置 "type": "module"。您需要使用 --experimental-modules 标志运行节点。

节点 9Node 9 中,它在标志后面启用,并使用 .mjs 扩展。

node --experimental-modules my-app.mjs

虽然 import 确实是 ES6 的一部分,但遗憾的是,默认情况下 NodeJS 还不支持 ,并且直到最近才在浏览器中获得支持。

请参阅 browser compat table on MDNthis Node issue

来自 James M Snell 的 Update on ES6 Modules in Node.js(2017 年 2 月):

工作正在进行中,但需要一些时间——我们目前正在考虑至少一年左右。

在原生支持 (now marked stable in Node 13+) 之前, 您必须继续使用经典的 require 语句

const express = require("express");

如果你真的想在 NodeJS 中使用新的 ES6/7 特性,你可以使用 Babel 编译它。 Here's an example server


有谁知道 node 10 是否会默认启用支持? (预计下个月出道)
@Scimonster ......node --experimental-modules my-app.mjs (node:12176) ExperimentalWarning:ESM 模块加载器是实验性的。 { 错误:在搜索中找不到模块 /C:/Users/WittyParrot/Documents/card-test-project/src/my-app.mjs (internal/modules/esm/DefaultResolve.js:23:12)test-project/搜索时的 src/my-app.mjs (internal/modules/esm/DefaultResolve.js:23:12)....抛出警告找不到 my-app.js....请建议....我安装节点版本 9.11.1
在 v12 nodejs.org/api/esm.html#esm_ecmascript_modules 中仍然需要一个标志
似乎 Node v13.2.0 无法将 ES 模块导入或导入()为“.js”,除非在其上方某处有一个带有 type: module 的 package.json。 esm 在这些情况下仍然有用。
题外话,但我无法安装节点 14,因为它不再支持 Windows 7。很遗憾,如果我想要完全支持导入/导出而没有任何标志,那么我必须升级我的操作系统。
b
baranskistad

不幸的是,Node.js 还不支持 ES6 的 import

要完成您要执行的操作(导入 Express 模块),此代码就足够了

var express = require("express");

另外,请确保您通过运行安装了 Express

$ npm install express

有关学习 Node.js 的更多信息,请参阅 Node.js Docs


import 不一定是 TypeScript 的功能。 TypeScript 是带有类型的 ES6。所以像 import 这样的东西是 ES6 原生的。
Node 现在本机支持这个,所以这个答案已经过时了
t
thedanotto

我很震惊 esm 没有被提及。这个小而强大的软件包允许您使用 importrequire

在你的项目中安装 esm

$ npm install --save esm

更新您的节点启动脚本以使用 esm

node -r esm app.js

esm 正常工作。我在 .mjs--experimental-modules 上浪费了大量时间,却发现 .mjs 文件无法导入使用 requiremodule.exports 的文件。这是一个很大的问题,而 esm 允许您混合搭配,它只是解决它... esm 只是工作。


如何使用 esm 通过 Visual Studio Code 调试器进行调试?我想直接按 F5 开始在 VSCode 中调试 js。
如果您使用的是 nodemon,请将您的 npm 脚本更新为 nodemon -r esm app.js 以使用此解决方案自动重新加载。
哇。我不相信这是真的,但确实如此。
b
baranskistad

正如其他答案中提到的,Node JS 目前不支持 ES6 导入。

(截至目前,请阅读 EDIT 2)

Enable ES6 imports in node js 提供了此问题的解决方案。我已经尝试过了,它对我有用。

运行命令:

    npm install babel-register babel-preset-env --save-dev

现在您需要创建一个新文件 (config.js) 并向其中添加以下代码。

    require('babel-register')({
        presets: [ 'env' ]
    })
    // Import the rest of our application.
    module.exports = require('./your_server_file.js')

现在您可以编写导入语句而不会出现任何错误。

希望这可以帮助。

编辑:

您需要运行使用上述代码创建的新文件。就我而言,它是 config.js。所以我必须运行:

    node config.js

编辑2:

在试验过程中,我发现了一个简单的解决方案。

在项目的根目录中创建 .babelrc 文件。

添加以下内容(以及您需要的任何其他 babel 预设,可以在此文件中添加):

    {
        "presets": ["env"]
    }

使用命令 npm install babel-preset-env --save 安装 babel-preset-env,然后使用命令 npm install babel-cli -g --save 安装 babel-cli

现在,转到您的服务器或索引文件所在的文件夹并使用以下命令运行: babel-node fileName.js

或者,您可以通过将以下代码添加到 package.json 文件来使用 npm start 运行:

    "scripts": {
        "start": "babel-node src/index.js"
    }

我如何用电子做到这一点?我试过这样:"start": "babel-node electron .", 但没有运气
@tpbafk 我没有研究过电子。但我发现了与您的问题 javascript - How to set npm start for electron app with 'babel-node --presets es2015,stage-3' 类似的问题。希望能帮助到你
V
VLAZ

错误:SyntaxError:意外的令牌导入或 SyntaxError:意外的令牌导出

解决方案:更改所有导入作为示例

const express               = require('express');
const webpack               = require('webpack');
const path                  = require('path');
const config                = require('../webpack.config.dev');
const open                  = require('open');

并将您的 export default = foo; 更改为 module.exports = foo;


我希望您能多解释一下导出默认部分。我在这部分遇到了麻烦。导入非常适合您的答案。
在我的答案之前有一个答案,其中有一个解释。但是为了澄清 Node 不支持 ES6 语法。当您说 Import ... 时,您使用的是 ES6 语法
A
Alberto

如果您仍然不能使用“导入”,我是这样处理的:只需将其转换为对节点友好的要求。例子:

import { parse } from 'node-html-parser';

是相同的:

const parse = require('node-html-parser').parse;

如果您(很可能)使用 export 关键字,则不正确
@DanielThompson 抱歉,如果这可能是误解,我只是为这种情况提供一种解决方法,如果您在没有 export 关键字的情况下工作,无论如何感谢您的有用说明!
为我工作。谢谢
J
Jason Ashley

babel 7 提案可以添加开发依赖吗

npm i -D @babel/core @babel/preset-env @babel/register

并在根目录中添加 .babelrc

{
"presets": [
  [
    "@babel/preset-env",
    {
      "targets": {
        "node": "current"
     }
    }
  ]
 ]
}

并添加到 .js 文件中

require("@babel/register")

或者如果你在 cli 中运行它,你可以使用 require 钩子作为 -r @babel/register,例如。

$node -r @babel/register executeMyFileWithESModules.js

安装 @babel/preset-env 并将其添加到 .babelrc 就可以了。在我的情况下不需要@babel/register 插件。
A
ASTOMUSIC

如果您可以使用“babel”,请尝试在 package.json(--presets=es2015) 中添加构建脚本,如下所示。它将导入代码预编译到 es2015

"build": "babel server --out-dir build --presets=es2015 && webpack"

但是我对 npm start 的调用会先执行“构建”,还是先执行“开始”? (当前定义的开始:"nodemon src/app.js --exec \"npm run lint && node\"",
如果我运行这个 cmd,它会显示服务器不存在错误
A
Ashok

当我开始使用 express 时,我一直想要一个使用 import 而不是 require 的解决方案

const express = require("express");
// to 
import express from "express"

很多时候都经过这条线:- Unfortunately, Node.js doesn't support ES6's import yet.

现在为了帮助其他人,我在这里创建了两个新的解决方案

1) esm:-

非常简单、无 babel、无捆绑的 ECMAScript 模块加载器。让它发挥作用

  yarn add esm / npm install esm

创建 start.js 或使用您的命名空间

 require = require("esm")(module/*, options*/)
 // Import the rest of our application.
 module.exports = require('./src/server.js')
 // where server.js is express server start file

更改 start.jspackage.josn 传递路径

  "scripts": {
    "start": "node start.js",
    "start:dev": "nodemon start.js",
  },
  "dependencies": {
+    "esm": "^3.2.25",
  },
  "devDependencies": {
+   "nodemon": "^1.19.2"
  }

2) Babel js:-

这可以分为2部分

a) Solution 1 感谢 timonweb.com

b) 解决方案 2

使用 Babel 6(旧版本的 babel-preset-stage-3 ^6.0)在您的根文件夹中创建 .babelrc 文件

{
    "presets": ["env", "stage-3"]
}

安装 babel-preset-stage-3

yarn add babel-cli babel-polyfill babel-preset-env bable-preset-stage-3 nodemon --dev

package.json 中的更改

"scripts": {
+   "start:dev": "nodemon --exec babel-node -- ./src/index.js",
+   "start": "npm run build && node ./build/index.js",
+   "build": "npm run clean && babel src -d build -s --source-maps --copy-files",
+   "clean": "rm -rf build && mkdir build"
},
"devDependencies": {
+    "babel-cli": "^6.26.0",
+    "babel-polyfill": "^6.26.0",
+    "babel-preset-env": "^1.7.0",
+    "babel-preset-stage-3": "^6.24.1",
+    "nodemon": "^1.19.4"
},

启动你的服务器

yarn start / npm start

哦不,我们创造了新的问题

regeneratorRuntime.mark(function _callee(email, password) {
^
ReferenceError: regeneratorRuntime is not defined

仅当您在代码中使用 async/await 时才会出现此错误。然后使用包含自定义再生器运行时和 core-js 的 polyfill。在 index.js 上添加

import "babel-polyfill"

这允许您使用 async/await

使用Babel 7

需要更新项目中的所有内容让我们从 babel 7 .babelrc 开始

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

package.json 的一些变化

"scripts": {
+  "start:dev": "nodemon --exec babel-node -- ./src/index.js",
+  "start": "npm run build && node ./build/index.js",
+  "build": "npm run clean && babel src -d build -s --source-maps --copy-files",
+  "clean": "rm -rf build && mkdir build",
    ....
}
"devDependencies": {
+   "@babel/cli": "^7.0.0",
+   "@babel/core": "^7.6.4",
+   "@babel/node": "^7.0.0",
+   "@babel/polyfill": "^7.0.0",
+   "@babel/preset-env": "^7.0.0",
+   "nodemon": "^1.19.4"
....
}

并在起点使用 import "@babel/polyfill"

import "@babel/polyfill"
import express from 'express'
const app = express()

//GET request
app.get('/', async (req, res) {
  // await operation
  res.send('hello world')
})
app.listen(4000, () => console.log('🚀 Server listening on port 400!'))

你在想为什么start:dev

严重地。如果你是新手,这是个好问题。每次更改都使用启动服务器然后使用 yarn start:dev 作为开发服务器每次更改都会自动重新启动服务器以获取更多关于 nodemon


T
T.J. Crowder

从 Node.js v12 开始(现在这可能相当稳定,但仍标记为“实验性”),您有几个使用 ESM 的选项(ECMAS Node.js 中的 cript Modules)(对于文件,还有第三种评估字符串的方法),the documentation 是这样说的:

--experimental-modules 标志可用于启用对 ECMAScript 模块(ES 模块)的支持。启用后,Node.js 在将以下内容作为 ES 模块传递给 node 作为初始输入时,或在 ES 模块代码中的 import 语句引用时:以 .mjs 结尾的文件。以 .js 结尾的文件或无扩展名文件,当最近的父 package.json 文件包含一个值为“module”的顶级字段“type”时。字符串作为参数传入--eval 或--print,或通过STDIN 管道传输到节点,带有标志--input-type=module。 Node.js 会将所有其他形式的输入视为 CommonJS,例如 .js 文件,其中最近的父 package.json 文件不包含顶级“type”字段,或者没有标志 --input-type 的字符串输入。此行为是为了保持向后兼容性。然而,既然 Node.js 支持 CommonJS 和 ES 模块,最好尽可能显式。当 Node.js 作为初始输入传递给 node 或被 ES 模块代码中的 import 语句引用时,Node.js 会将以下内容视为 CommonJS: 以 .cjs 结尾的文件。当最近的父 package.json 文件包含值为“commonjs”的顶级字段“type”时,以 .js 结尾的文件或无扩展名文件。字符串作为参数传入 --eval 或 --print,或通过 STDIN 管道传输到节点,带有标志 --input-type=commonjs。


T
Tim Hardy

我将在原始问题中解决其他人没有的另一个问题。最近在我自己的 NodeJS 项目中从 CommonJS 转换为 ESM 之后,我几乎没有看到有人讨论过你不能将导入放在任何你想要的地方,就像你可以使用 require 一样。我的项目现在可以很好地使用导入,但是当我使用问题中的代码时,我首先收到一个错误,因为没有命名函数。命名函数后,我收到以下内容...

import express from 'express'
       ^^^^^^^

SyntaxError: Unexpected identifier
    at Loader.moduleStrategy (internal/modules/esm/translators.js:88:18)

您不能像您需要的那样将导入放置在函数中。它们必须放在文件的顶部,在代码块之外。我自己在这个问题上浪费了很多时间。

因此,尽管上述所有答案都非常适合帮助您在项目中使用导入,但没有一个答案可以解决原始问题中的代码无法按书面形式工作的事实。


谢谢,这就是问题所在,虽然很烦人。我在顶部的导入列表将有 100 行长。当与特定 API 调用有关的所有内容都集中在一个位置时,可以更轻松地进行管理
A
Abhijeet Singh

从版本 14.x LTS 开始,Node 的稳定版本支持 import 语句。

您只需在 package.json 中指定 "type": "module"


我使用节点 14.17.5 但不能使用 import
支持。但并非没有额外的配置。您仍然需要像我提到的那样指定 "type": "module",或者为您的文件使用 .mjs 扩展名。
G
Ghita Tomoiaga

在我的例子中,它正在处理 .babelrc 文件,它应该包含如下内容:

{
  "presets": ["es2015-node5", "stage-3"],
  "plugins": []
}

B
Binita Bharati

我的项目使用 node v10.21.0,它仍然不支持 ES6 import 关键字。有多种方法可以让节点识别 import,其中一种是以 node --experimental-modules index.mjs 开头的节点(mjs 扩展名已包含在此处的答案之一中)。但是,这样一来,您将无法在代码中使用像 require 这样的节点特定关键字。如果需要同时使用 nodejs 的 require 关键字和 ES6 的 import,那么出路是使用 esm npm 包。添加 esm 包作为依赖项后,需要使用特殊配置启动节点,例如:node -r esm index.js


J
James

我一直在努力让这个工作。这是有效的:

使用最新的节点版本。我正在使用 v14.15.5。通过运行验证您的版本: node --version 命名文件,使它们都以 .mjs 而不是 .js 结尾

例子:

模组.mjs

export const STR = 'Hello World'

测试.mjs

import {STR} from './mod.mjs'
console.log(STR)

运行:节点test.mjs

您应该看到“Hello World”。


A
Abhishek Kumar

只需安装更高版本的 Node.js。不支持 Node v10 es6。您需要禁用一些标志或使用