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

时间:2016-09-11 12:55:44

标签: javascript node.js npm ecmascript-6

我不明白出了什么问题。 节点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

17 个答案:

答案 0 :(得分:363)

更新:在Node 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月):

  

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

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

const express = require("express");

如果您真的想在NodeJS中使用新的ES6 / 7功能,可以使用Babel进行编译。 Here's an example server

答案 1 :(得分:48)

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

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

var express = require("express");

另外,请确保通过运行

安装了Express
$ npm install express

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

答案 2 :(得分:29)

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

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



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;

答案 3 :(得分:17)

如其他答案中所述,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"]
    }

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

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

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

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

答案 4 :(得分:8)

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

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

答案 5 :(得分:7)

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

<de.hdodenhof.circleimageview.CircleImageView
    android:layout_width="@dimen/_60sdp"
    android:layout_height="@dimen/_60sdp"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:id="@+id/doctorDetailsImg"
    android:layout_marginTop="@dimen/_4sdp"
    app:civ_border_width="@dimen/_2sdp"
    android:scaleType="centerCrop"
    app:civ_border_color="@color/green"
    android:src="@drawable/mahmoud" />

与:

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

答案 6 :(得分:4)

我没有为esm感到震惊。这个小巧但功能强大的软件包允许您使用importrequire

在项目中安装esm

$ npm install --save esm

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

node -r esm app.js

esm就可以了。我在.mjs--experimental-modules上浪费了大量时间,只是为了找出.mjs文件无法导入使用requiremodule.exports的文件。这是一个很大的问题,而esm允许您进行混合和匹配,并且可以弄清楚……esm可以正常工作。

答案 7 :(得分:3)

我要解决其他人没有的原始问题中的另一个问题。最近在我自己的NodeJS项目中从CommonJS转换为ESM之后,我很少看到关于无法将导入放置在所需位置的事实的讨论,就像需要require一样。我的项目现在可以很好地处理导入,但是当我使用问题中的代码时,由于没有命名函数,我首先遇到一个错误。命名功能后,我收到以下信息...

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

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

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

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

答案 8 :(得分:2)

当我开始使用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

更改package.josn的{​​{1}}通过路径

start.js

2)Babel js:-

这可以分为2部分

a)Solution 1感谢timonweb.com

b)解决方案2

使用Babel 6(旧版本的babel-preset-stage-3 ^6.0)  在您的根文件夹中创建 "scripts": { "start": "node start.js", "start:dev": "nodemon start.js", }, "dependencies": { + "esm": "^3.2.25", }, "devDependencies": { + "nodemon": "^1.19.2" } 文件

.babelrc

安装babel-preset-stage-3

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

package.json中的更改

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

启动服务器

"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

仅当您在代码中使用async / await时,才会出现此错误。 然后使用包含自定义再生器运行时和core-js的polyfill。 在regeneratorRuntime.mark(function _callee(email, password) { ^ ReferenceError: regeneratorRuntime is not defined

上添加
index.js

这允许您使用异步/等待

使用Babel 7

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

import "babel-polyfill"

package.json中的某些更改

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

并在起点上使用"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用作开发服务器,每个更改重新启动服务器会自动在nodemon

中使用

答案 9 :(得分:1)

在我的情况下,它正在寻找.babelrc文件,并且其中应包含以下内容:

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

答案 10 :(得分:1)

我的项目使用 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

答案 11 :(得分:0)

我一直在努力让它发挥作用。这是有效的:

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

示例:

mod.mjs

export const STR = 'Hello World'

test.mjs

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

运行: node test.mjs

您应该会看到“Hello World”。

答案 12 :(得分:0)

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

import语句。

您需要做的就是在"type": "module"中指定package.json

答案 13 :(得分:0)

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

答案 14 :(得分:0)

我经常使用github入门项目,例如this(它使用babel)

答案 15 :(得分:0)

从Node.js v12开始(现在可能相当稳定,但仍标记为“实验性”),您可以使用ESM( E CMA S < / strong> cript M 条指令)(对于文件,还有第三种逃避字符串的方法),这就是the documentation所说的:

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

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

  • .mjs结尾的文件。

  • .js结尾的文件或无扩展名的文件(如果是最近的父文件) package.json文件包含一个顶级字段"type",其值为 "module"

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

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

  • .cjs结尾的文件。

  • .js结尾的文件或无扩展名的文件(如果是最近的父文件) package.json文件包含一个顶级字段"type",其值为 "commonjs"

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

答案 16 :(得分:0)

babel 7提案 您可以添加开发人员依赖项

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

并在根目录中添加.babelrc

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

并添加到.js文件

require("@babel/register")