繁体   English   中英

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

[英]Node.js - SyntaxError: Unexpected token import

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

Node 13+Node 13开始,您可以使用.mjs扩展名,或在 package.json 中设置{"type": "module"} 不需要使用--experimental-modules标志。 模块现在在 node.js 中被标记为稳定

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

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

node --experimental-modules my-app.mjs

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

请参阅MDN 上的浏览​​器兼容表此节点问题

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

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

在原生支持出现之前( 现在在 Node 13+ 中标记为稳定), 您必须继续使用经典的 require语句

const express = require("express");

如果你真的想在 NodeJS 中使用新的 ES6/7 特性,你可以使用 Babel 编译它。 这是一个示例服务器

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

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

var express = require("express");

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

$ npm install express

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

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

在你的项目中安装 esm

$ npm install --save esm

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

node -r esm app.js

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

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

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

在 node js 中启用 ES6 导入为这个问题提供了解决方案。 我已经尝试过了,它对我有用。

运行命令:

    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- babel-preset-env npm install babel-preset-env --save ,然后使用命令 npm install babel-cli npm install babel-cli -g --save

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

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

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

错误: 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;

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

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

是相同的:

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

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”,请尝试在 package.json(--presets=es2015) 中添加构建脚本,如下所示。 它将导入代码预编译到 es2015

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

当我开始使用 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)通天塔 js :-

这可以分为2部分

a)解决方案 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

使用通天塔 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

从 Node.js v12 开始(现在这可能相当稳定,但仍标记为“实验性”),您有几个选项可以在Node.js中使用 ESM( E CMA S脚本模块)(对于文件,有一个第三种评估字符串的方法),这是文档所说的

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

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

  • .mjs结尾的文件。

  • .js结尾的文件,或无扩展名的文件,当最近的父package.json文件包含一个值为"module"的顶级字段"type"时。

  • 字符串作为参数传递给--eval--print ,或通过STDIN管道传输到node ,带有标志--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结尾的文件。

  • .js结尾的文件或无扩展名文件,当最近的父package.json文件包含一个值为"commonjs"的顶级字段"type"时。

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

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

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

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

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

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

自版本 14.x LTS 起,Node 的稳定版本支持import语句。

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

就我而言,它正在处理.babelrc文件,它应该包含如下内容:

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

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

我不明白怎么了。 节点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

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

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

例子:

模组.mjs

export const STR = 'Hello World'

测试.mjs

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

运行:节点test.mjs

您应该看到“Hello World”。

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

暂无
暂无

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

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