如何在Node.js中使用ES6导入?

如何在Node.js中使用ES6导入?,node.js,es6-modules,Node.js,Es6 Modules,我试图在Node.js中了解ES6导入的诀窍,并尝试使用本例中提供的语法: 我正在查看,但找不到支持新导入语句的版本(我尝试查找文本import/require)。我目前正在运行Node.js 8.1.2,而且我还相信,由于备忘单是指.js文件,所以它应该与.js文件一起使用 当我运行代码时(取自备忘单的第一个示例): 我得到一个错误: SyntaxError:意外的令牌导入 对我尝试导入的库的引用: //------ lib.js ------ export const sqrt = Math

我试图在Node.js中了解ES6导入的诀窍,并尝试使用本例中提供的语法:

我正在查看,但找不到支持新导入语句的版本(我尝试查找文本import/require)。我目前正在运行Node.js 8.1.2,而且我还相信,由于备忘单是指.js文件,所以它应该与.js文件一起使用

当我运行代码时(取自备忘单的第一个示例):

我得到一个错误:

SyntaxError:意外的令牌导入

对我尝试导入的库的引用:

//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}
我遗漏了什么?如何让
节点
识别我的
导入
语句

Node.js包含了对ES6支持的实验支持。 请在此处阅读更多信息:

TLDR

Node.js>=v13

在Node.js 13及更高版本中非常简单。您需要:

  • .mjs
    扩展名保存文件,或
  • 在最近的
    package.json
    中添加
    {“type”:“module”}
您只需执行上述操作之一即可使用ECMAScript模块


Node.js您可以尝试
esm


这里有一些介绍:

如果您使用的是服务器端的模块系统,则根本不需要使用。要使用Node.js中的模块,请确保:

  • 使用支持--实验模块标志的节点版本
  • 您的*.js文件必须重命名为*.mjs
  • 就这样

    然而,这是一个大问题,尽管您的shinny纯ES6代码将在Node.js(例如9.5.0)这样的环境中运行,但您仍然会疯狂地传输以进行测试。还要记住,Ecma已经声明JavaScript的发布周期将更快,更新的特性将更定期地交付。虽然对于Node.js这样的单一环境来说这不会有问题,但对于浏览器环境来说,这是一个稍微不同的主张。很明显,测试框架在追赶上还有很多工作要做。对于测试框架,您可能仍然需要使用transbile。我建议使用

    还要注意绑定框架。您将在那里遇到问题。

    返回到的原始问题

    “…哪个版本支持新的ES6导入语句?”

    基于,有一个计划在Node.js 10.x LTS中默认支持它(不带实验性命令行标志)。根据2018年3月29日的情况,它很可能在2018年4月后可用,,而它的LTS将在2018年10月开始

    解决方案

    下面是文件*mixins/index.js的定义
    这在我的Node.js CLI应用程序中运行得很好。

    我只想在JavaScript文件中使用
    导入
    导出

    每个人都说这是不可能的。但是,从2018年5月起,可以在plain Node.js中使用上述内容,而不需要任何模块,如等

    下面是一个简单的方法

    创建以下文件,运行,并亲自查看输出

    另外,不要忘记查看下面的
    说明

    文件myfile.mjs 文件index.mjs 跑 输出 说明:

  • 由于是实验模块,.js文件被命名为.mjs文件
  • 运行时,您将向
    节点索引.mjs添加
    --实验模块
  • 在输出中使用实验模块运行时,您将看到:“(节点:12020)实验警告:ESM模块加载程序是实验性的。 "
  • 我有Node.js的最新版本,所以如果我运行
    Node--version
    ,它会给出“v10.3.0”,尽管LTE/stable/recommended版本是8.11.2 LTS
  • 将来的某一天,您可以使用.js而不是.mjs,因为这些特性变得稳定而不是实验性的
  • 有关实验功能的更多信息,请参见:

  • 我不知道这是否适用于您的案例,但我正在运行一台带有以下内容的服务器:

    nodemon --inspect ./index.js --exec babel-node --presets es2015,stage-2
    
    这使我能够导入和使用spread运算符,即使我只使用Node.js版本8

    您需要安装babel cli、babel-preset-es2015和babel-preset-stage-2来完成我的工作。

    使用:

      "devDependencies": {
        "@babel/core": "^7.2.0",
        "@babel/preset-env": "^7.2.0",
        "@babel/register": "^7.0.0"
      }
    
    文件名:babelrc Node.js应用程序的入口点:
    请参见

    您还可以使用名为的npm包,该包允许您在Node.js中使用ES6模块。它不需要配置。使用esm,您将能够在JavaScript文件中使用导出/导入

    在终端上运行以下命令

    yarn add esm
    

    npm install esm
    
    之后,在使用节点启动服务器时,需要使用此包。例如,如果您的节点服务器运行index.js文件,您将使用以下命令

    node -r esm index.js
    
    您还可以像下面这样将其添加到package.json文件中

    {
      "name": "My-app",
      "version": "1.0.0",
      "description": "Some Hack",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "node -r esm index.js"
      },
    
    }
    
    然后从终端运行此命令以启动节点服务器

    npm start
    

    查看更多详细信息。

    使用
    .mjs
    扩展名(如接受的答案中所建议的)以启用ECMAScript模块。但是,使用Node.js v12,您还可以在
    package.json
    文件中全局启用此功能

    委员会:

    如果最近的父package.json包含“type”:“module”,则.js和无扩展文件的导入语句将被视为ES模块


    (当然,在启动应用程序时,您仍然必须提供标志
    --实验模块

    使用Node.js v12.2.0,我可以像这样导入所有标准模块:

    import * as Http from 'http'
    import * as Fs from 'fs'
    import * as Path from 'path'
    import * as Readline from 'readline'
    import * as Os from 'os'
    
    // Implement the old require function
    import { createRequire } from 'module'
    const require = createRequire(import.meta.url)
    
    // Now you can require whatever
    const
      WebSocket = require('ws')
      ,Mime = require('mime-types')
      ,Chokidar = require('chokidar')
    
    与我之前所做的相比:

    const
      Http = require('http')
      ,Fs = require('fs')
      ,Path = require('path')
      ,Readline = require('readline')
      ,Os = require('os')
    
    作为ECMAScript模块的任何模块都可以导入,而无需使用.mjs扩展名,只要它的package.json文件中有以下字段:

    "type": "module"
    
    因此,请确保将这样一个package.json文件与正在制作的模块放在同一个文件夹中

    要导入未使用ECMAScript模块支持更新的模块,可以执行以下操作:

    import * as Http from 'http'
    import * as Fs from 'fs'
    import * as Path from 'path'
    import * as Readline from 'readline'
    import * as Os from 'os'
    
    // Implement the old require function
    import { createRequire } from 'module'
    const require = createRequire(import.meta.url)
    
    // Now you can require whatever
    const
      WebSocket = require('ws')
      ,Mime = require('mime-types')
      ,Chokidar = require('chokidar')
    
    npm install esm
    
    node -r esm index.js
    
    {
      "name": "My-app",
      "version": "1.0.0",
      "description": "Some Hack",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "node -r esm index.js"
      },
    
    }
    
    npm start
    
    {
      "type": "module",
      "main": "./src/index.js"
    }
    
    import * as Http from 'http'
    import * as Fs from 'fs'
    import * as Path from 'path'
    import * as Readline from 'readline'
    import * as Os from 'os'
    
    const
      Http = require('http')
      ,Fs = require('fs')
      ,Path = require('path')
      ,Readline = require('readline')
      ,Os = require('os')
    
    "type": "module"
    
    // Implement the old require function
    import { createRequire } from 'module'
    const require = createRequire(import.meta.url)
    
    // Now you can require whatever
    const
      WebSocket = require('ws')
      ,Mime = require('mime-types')
      ,Chokidar = require('chokidar')
    
    node --experimental-modules my-script-that-use-import.js
    
    {
      "type": "module"
    }