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

Sof*_*oid 388 javascript node.js npm ecmascript-6

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

代码:

function (exports, require, module, __filename, __dirname) {
    import express from 'express'
};
Run Code Online (Sandbox Code Playgroud)

错误:

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
Run Code Online (Sandbox Code Playgroud)

Sci*_*ter 424

更新:节点9中,它在标志后面启用,并使用--experimental-modules扩展名.

node --experimental-modules my-app.mjs
Run Code Online (Sandbox Code Playgroud)

虽然.mjs确实是ES6的一部分,但遗憾的是,NodeJS默认不支持它,并且最近才在浏览器中获得支持.

请参阅MDN上的浏览器compat表此Node问题.

来自James M Snell 对Node.js中ES6模块更新(2017年2月):

工作正在进行中,但需要一些时间 - 我们目前至少要看一年左右.

在支持本地显示之前,您必须继续使用经典"type": "module"语句:

const express = require("express");
Run Code Online (Sandbox Code Playgroud)

如果您真的想在NodeJS中使用新的ES6/7功能,可以使用Babel进行编译.这是一个示例服务器.

  • 令人沮丧的是因为大多数教程都在谈论使用import,但几乎没有支持它.(我想要2小时的生命回来哈哈) (32认同)
  • @ChaimEliyah:在节点v11.0.0中遇到了同样的问题 (9认同)
  • 在v12 https://nodejs.org/api/esm.html#esm_ecmascript_modules中仍然需要标记 (4认同)
  • 有谁知道默认情况下节点10是否附带支持?(由于下个月首演) (2认同)
  • @Scimonster......node --experimental-modules my-app.mjs (node:12176) 实验警告: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 at search (internal/modules/esm/DefaultResolve.js:23:12)....抛出警告找不到 my-app.js....请建议....i已安装节点版本 9.11.1 (2认同)
  • 题外话,但我无法安装节点 14,因为它不再支持 Windows 7。令人遗憾的是,如果我想在没有任何标志的情况下完全支持导入/导出,那么我必须升级我的操作系统。 (2认同)

bar*_*tad 54

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

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

var express = require("express");
Run Code Online (Sandbox Code Playgroud)

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

$ npm install express
Run Code Online (Sandbox Code Playgroud)

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

  • `import`不一定是TypeScript的一个功能.TypeScript是带有打字的ES6.所以像import这样的东西是ES6原生的. (8认同)
  • 节点现在原生支持这个,所以这个答案已经过时了 (2认同)

the*_*tto 44

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

在你的项目中安装 esm

$ npm install --save esm

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

node -r esm app.js

esm只是工作。我浪费的时间TON与.mjs--experimental-modules只找出一个.mjs文件无法导入文件使用requiremodule.exports。这是一个巨大的问题,而esm允许您混合和匹配,它只是想通了......esm只是有效。


sup*_*289 31

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


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

const express 				= require('express');
const webpack				= require('webpack');
const path				= require('path');
const config				= require('../webpack.config.dev');
const open 				= require('open');
Run Code Online (Sandbox Code Playgroud)

并且还要改变你export default = foo;module.exports = foo;


Nee*_*rya 26

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

在节点js中启用ES6导入可提供此问题的解决方案.我已经厌倦了,这对我有用.

运行命令:

    npm install babel-register babel-preset-env --save-dev
Run Code Online (Sandbox Code Playgroud)

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

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

现在您可以编写import语句而不会出现任何错误.

希望这可以帮助.

编辑:

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

    node config.js
Run Code Online (Sandbox Code Playgroud)

  • @tpbafk我还没有研究电子。但是我发现了与您的问题类似的东西[javascript-如何使用'babel-node --presets es2015,stage-3'为电子应用设置npm start] [/sf/ask/3220990671/设置npm-启动电子应用程序,并带有Babel节点预设-es2015-stage-3 / 46014302)。希望能帮助到你 (2认同)

Alb*_*rto 12

如果仍然不能使用“导入”,这就是我的处理方式:只需将其转换为对节点友好的需求即可。例:

import { parse } from 'node-html-parser';
Run Code Online (Sandbox Code Playgroud)

是相同的:

const parse = require('node-html-parser').parse;
Run Code Online (Sandbox Code Playgroud)

  • 如果您(可能)使用`export`关键字,则为true (4认同)

小智 8

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

"build": "babel server --out-dir build --presets=es2015 && webpack"
Run Code Online (Sandbox Code Playgroud)


Jas*_*ley 8

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

npm i -D @babel/core @babel/preset-env @babel/register
Run Code Online (Sandbox Code Playgroud)

并在根目录中添加.babelrc

{
"presets": [
  [
    "@babel/preset-env",
    {
      "targets": {
        "node": "current"
     }
    }
  ]
 ]
}
Run Code Online (Sandbox Code Playgroud)

并添加到.js文件

require("@babel/register")
Run Code Online (Sandbox Code Playgroud)

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

$node -r @babel/register executeMyFileWithESModules.js
Run Code Online (Sandbox Code Playgroud)

  • 安装 @babel/preset-env 并将其添加到 .babelrc 就成功了。在我的情况下不需要@babel/register 插件。 (2认同)

T.J*_*der 8

随着Node.js的V12的(这是现在可能还算稳定,但仍标有“实验性”),你有两个选择使用ESM(ē CMA小号CRIPT中号在Node.js的odules)(的文件,有一个评估字符串的第三种方法),这是文档所说的:

--experimental-modules标志可用于启用对 ECMAScript 模块(ES 模块)的支持。

启用后,Node.js 将在作为node初始输入传递给以下内容时,或import在 ES 模块代码中的语句引用时将以下内容视为 ES 模块 :

  • 结尾的文件.mjs

  • 结尾的文件.js,或名的文件,当最近的父 package.json文件中包含顶级场"type"用的值 "module"

  • 字符串作为参数传递给--evalor --print,或node通过管道传递给 via STDIN,带有标志--input-type=module

Node.js 会将所有其他形式的输入视为 CommonJS,例如.js最近的父package.json文件不包含顶级"type" 字段的文件,或没有标志的字符串输入--input-type。此行为是为了保持向后兼容性。然而,现在 Node.js 同时支持 CommonJS 和 ES 模块,最好尽可能明确。当node作为初始输入传递给 Node.js或被importES 模块代码中的语句引用时,Node.js 会将以下内容视为 CommonJS :

  • 结尾的文件.cjs

  • 结尾的文件.js,或名的文件,当最近的父 package.json文件中包含顶级场"type"用的值 "commonjs"

  • 字符串作为参数传递给--evalor --print,或node通过管道传递给 via STDIN,带有标志--input-type=commonjs


Ash*_*hok 8

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

const express = require("express");
// to 
import express from "express"
Run Code Online (Sandbox Code Playgroud)

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

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

1) esm :-

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

  yarn add esm / npm install esm
Run Code Online (Sandbox Code Playgroud)

创建 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
Run Code Online (Sandbox Code Playgroud)

改变你的package.josn通行证路径start.js

  "scripts": {
    "start": "node start.js",
    "start:dev": "nodemon start.js",
  },
  "dependencies": {
+    "esm": "^3.2.25",
  },
  "devDependencies": {
+   "nodemon": "^1.19.2"
  }
Run Code Online (Sandbox Code Playgroud)

2)巴别 js :-

这可以分为 2 部分

a)解决方案 1感谢 timonweb.com

b)解决方案 2

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

{
    "presets": ["env", "stage-3"]
}
Run Code Online (Sandbox Code Playgroud)

安装 babel-preset-stage-3

yarn add babel-cli babel-polyfill babel-preset-env bable-preset-stage-3 nodemon --dev
Run Code Online (Sandbox Code Playgroud)

更改 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"
},
Run Code Online (Sandbox Code Playgroud)

启动你的服务器

yarn start / npm start
Run Code Online (Sandbox Code Playgroud)

哦不,我们创造了新问题

regeneratorRuntime.mark(function _callee(email, password) {
^
ReferenceError: regeneratorRuntime is not defined
Run Code Online (Sandbox Code Playgroud)

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

import "babel-polyfill"
Run Code Online (Sandbox Code Playgroud)

这允许您使用 async/await

使用巴别塔 7

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

{
  "presets": ["@babel/preset-env"]
}
Run Code Online (Sandbox Code Playgroud)

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"
....
}
Run Code Online (Sandbox Code Playgroud)

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!'))
Run Code Online (Sandbox Code Playgroud)

你在想为什么 start:dev

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


Tim*_*rdy 7

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

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

SyntaxError: Unexpected identifier
    at Loader.moduleStrategy (internal/modules/esm/translators.js:88:18)
Run Code Online (Sandbox Code Playgroud)

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

因此,虽然上述所有答案都非常有助于您在项目中导入工作,但没有一个答案解决了原始问题中的代码无法按编写的方式工作的事实。