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

Javascript Node.js-SyntaxError:意外的令牌导入,javascript,node.js,npm,ecmascript-6,Javascript,Node.js,Npm,Ecmascript 6,我不明白怎么了。 节点v5.6.0 NPM v3.10.6 守则: 错误: 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:

我不明白怎么了。 节点v5.6.0 NPM v3.10.6

守则:

错误:

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.js还不支持ES6的
import

要完成您试图完成的任务(导入Express模块),此代码应该足够了

var express = require("express");
另外,请确保已通过运行安装了Express

$ npm install express

有关learning Node.js的更多信息,请参见。

节点13+,因为您可以使用
.mjs
扩展名,或者在package.json中设置
{“type”:“module”}
。您不需要使用
--experimental modules
标志

节点12因为,您可以使用
.mjs
扩展名,或者在package.json中设置
“type”:“module”
。您需要使用
--实验模块
标志运行节点

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

node --experimental-modules my-app.mjs

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

见和

摘自James M Snell(2017年2月):

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

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


如果您真的想在NodeJS中使用新的ES6/7特性,可以使用Babel编译它

错误:语法错误:意外标记导入或语法错误:意外标记导出


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

const express=require('express');
const webpack=require('webpack');
const path=require('path');
const config=require('../webpack.config.dev');
常量打开=需要(“打开”);

并更改您的
导出默认值=foo
module.exports=foo

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

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

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

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

如其他答案中所述,Node JS目前不支持ES6导入

(现在,请阅读编辑2)

提供了此问题的解决方案。我试过这个,它对我有效

运行以下命令:

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

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

或者您可以使用
npm start
运行,方法是将以下代码添加到
package.json
文件中:

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

如果您仍然无法使用“导入”,我将按照以下方式进行处理: 只需将其转换为节点友好型。例如:

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

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

巴别塔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
从Node.js v12开始(现在可能相当稳定,但仍然标记为“实验”),您有两个选项可以在Node.js中使用ESM(ECMASscriptModules)(对于文件,有第三种方法可以计算字符串),如下所示:

--实验模块
标志可用于支持 ECMAScript模块(ES模块)

一旦启用,Node.js将在传递给时将以下内容视为ES模块
节点
作为初始输入,或在中被
导入
语句引用时 ES模块代码:

  • .mjs
    结尾的文件

  • 当最接近的父级时,以
    .js
    结尾的文件或无扩展文件
    package.json
    文件包含一个值为的顶级字段
    “type”
    “模块”

  • 字符串作为参数传入到
    --eval
    --print
    ,或通过管道传送到
    节点
    通过
    STDIN
    ,标记为
    --输入类型=模块

Node.js将把所有其他形式的输入(如
.js
文件)视为CommonJS 其中最近的父级
package.json
文件不包含顶级
“type”
字段或不带标志的字符串输入<代码>--输入类型
。这种行为是为了 保持向后兼容性。但是,现在Node.js支持这两种方法 CommonJS和ES模块,最好尽可能显式。Node.js 当传递到
节点
作为初始输入时,将以下内容视为CommonJS, 或当ES模块代码中的
import
语句引用时:

  • .cjs
    结尾的文件

  • 当最接近的父级时,以
    .js
    结尾的文件或无扩展文件
    package.json
    文件包含一个顶级字段
    “ty
    
    {
    "presets": [
      [
        "@babel/preset-env",
        {
          "targets": {
            "node": "current"
         }
        }
      ]
     ]
    }
    
    require("@babel/register")
    
    $node -r @babel/register executeMyFileWithESModules.js
    
    const express = require("express");
    // to 
    import express from "express"
    
      yarn add esm / npm install esm
    
     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
    
      "scripts": {
        "start": "node start.js",
        "start:dev": "nodemon start.js",
      },
      "dependencies": {
    +    "esm": "^3.2.25",
      },
      "devDependencies": {
    +   "nodemon": "^1.19.2"
      }
    
    {
        "presets": ["env", "stage-3"]
    }
    
    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
    
    regeneratorRuntime.mark(function _callee(email, password) {
    ^
    ReferenceError: regeneratorRuntime is not defined
    
    import "babel-polyfill"
    
    {
      "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 express from 'express'
    const app = express()
    
    //GET request
    app.get('/', async (req, res) {
      // await operation
      res.send('hello world')
    })
    app.listen(4000, () => console.log('I'm shocked 
    esm
    hasn't been mentioned. This small, but mighty package allows you to use either
    import
    or
    require
    .

    Install esm in your project

    $ npm install --save esm

    Update your Node Start Script to use esm

    node -r esm app.js

    esm
    just works. I wasted a TON of time with
    .mjs
    and
    --experimental-modules
    only to find out a
    .mjs
    file cannot import a file that uses
    require
    or
    module.exports
    . This was a huge problem, whereas
    esm
    allows you to mix and match and it just figures it out...
    esm
    just works.

    I'm going to address another problem within the original question that no one else has. After recently converting from CommonJS to ESM in my own NodeJS project, I've seen very little discussion about the fact that you cannot place imports wherever you want, like you could with require. My project is working great with imports now, but when I use the code in the question, I first get an error for not having a named function. After naming the function, I receive the following...

    import express from 'express'
           ^^^^^^^
    
    SyntaxError: Unexpected identifier
        at Loader.moduleStrategy (internal/modules/esm/translators.js:88:18)
    
    export const STR = 'Hello World'
    
    import {STR} from './mod.mjs'
    console.log(STR)