如何在节点中使用es6导入?

Jon*_*002 240 node.js es6-modules

我试图在节点中获取es6导入的挂起,并尝试使用此示例中提供的语法:

Cheatsheet链接:https://hackernoon.com/import-export-default-require-commandjs-javascript-nodejs-es6-vs-cheatsheet-different-tutorial-example-5a321738b50f

我正在查看支持表:http://node.green/,但无法找到支持新导入语句的版本(我尝试查找文本import/require)我目前正在运行节点8.1. 2并且还认为,由于cheatsheet是指.js文件,它应该与.js文件一起使用.

当我运行代码时(取自cheatsheet的第一个例子):

import { square, diag } from 'lib';
Run Code Online (Sandbox Code Playgroud)

我收到错误:SyntaxError:意外的令牌导入.

参考lib我正在尝试导入:

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

我缺少什么,如何让节点识别我的import语句?

tbk*_*ing 171

Node.js包含了对ES6支持的实验性支持.在此处阅读更多信息:https://nodejs.org/api/esm.html.

TLDR; 使用带.mjs扩展名的ES6模块保存文件并运行它:

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

Node.js不支持ES6模块.詹姆斯的这篇博客描述了它的原因.虽然您可以使用Babel来使用ES6模块语法.

  • 如果您在package.json中包含`“ type”:“ module”`以及标志`node --experimental-modules my-app.js`,则可以使用.js文件扩展名。 (5认同)
  • @tbking,谢谢你的文章.了解我们的工作非常重要.对不起,请您添加工作示例?它应该只有2-3行:导入依赖项,然后导入目标类,然后创建实例. (3认同)
  • 好吧,我尝试了这种方法,但是在.mjs文件中有一个require语句,然后抛出错误“ require is not defined”(未定义)或其他错误 (3认同)
  • 这个答案对我有帮助!如果有人需要的话,我添加了一个与 Typescript 一起使用的示例:https://github.com/Urigo/typescript-node-es-modules-example (3认同)
  • 有关工作示例,请参阅 /sf/answers/3544911261/ (2认同)
  • @JTHouk 仅在 v13 之前才需要该标志,现在该标志已被删除。Nodejs v13 要求当前目录或父目录中的某个位置有 package.json 并在其中包含 `{"type": "module"}` 并且您可以使用 ES6 导入。来自文档:“当最近的父 package.json 文件包含值为“module”的顶级字段“type”时,以 .js 结尾或缺少任何扩展名的文件将作为 ES 模块加载。请在此处查看更多信息:https ://nodejs.org/api/esm.html#esm_package_json_type_field (2认同)
  • 请注意 - 导入模块时,重要的是编写完整路径并向文件名添加 .js 扩展名(这与浏览器的行为相同,但不是 webpack,它会为您完成扩展名和 /index.js),否则节点会抛出错误`代码:'ERR_MODULE_NOT_FOUND'` (2认同)

Seu*_*ope 161

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

在终端上运行以下命令

yarn add esm 
Run Code Online (Sandbox Code Playgroud)

要么

npm install esm
Run Code Online (Sandbox Code Playgroud)

之后,在使用节点启动服务器时需要此包.例如,如果节点服务器运行index.js文件,则可以使用该命令

node -r esm index.js
Run Code Online (Sandbox Code Playgroud)

你也可以像这样在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"
  },

}
Run Code Online (Sandbox Code Playgroud)

您也可以从终端运行此命令以启动节点服务器

npm start
Run Code Online (Sandbox Code Playgroud)

查看此链接了解更多详情

  • 这应该是公认的答案。 (15认同)
  • 我最喜欢这个答案。 (5认同)
  • 这是艾斯!不幸的是,这对 Jest 不起作用 (3认同)
  • 这是与Typescript一起使用的最佳选择,因为`ts-node`加载器使`.mjs`扩展名不可行。`node -r esm -r ts-node / register index.ts` (2认同)

Man*_*ddy 117

浪费了大约3个小时.

我只是想在js文件中使用importexport.

每个人都说不可能.但是,从2018年5月开始,可以在普通的node.js中使用上面的内容,而不需要像babel等那样的模块.

这是一个简单的方法.

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

另外别忘了看Explanation下面.

myfile.mjs

function myFunc() {
    console.log("Hello from myFunc")
}

export default myFunc;
Run Code Online (Sandbox Code Playgroud)

index.mjs

import myFunc from "./myfile.mjs"  // simply using "./myfile" may not work in all resolvers

myFunc();
Run Code Online (Sandbox Code Playgroud)

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

产量

(node:12020) ExperimentalWarning: The ESM module loader is experimental.

Hello from myFunc
Run Code Online (Sandbox Code Playgroud)

说明:

  1. 由于它是实验模块,.js文件被命名为.mjs文件
  2. 在运行时,您将"--experimental-modules"添加到"node index.js"
  3. 在输出中使用实验模块运行时,您将看到:"(节点:12020)实验警告:ESM模块加载器是实验性的."
  4. 我有当前版本的节点js,所以如果我运行"node --version",它会给我"v10.3.0",尽管LTE /稳定/推荐版本是8.11.2 LTS.
  5. 将来的某一天,你可以使用.js代替.mjs,因为你变得稳定而不是实验.
  6. 有关实验性功能的更多信息,请参阅:https://nodejs.org/api/esm.html

希望有所帮助.

  • 这在Node 10.15.1中为我工作 (3认同)
  • 我认为要使此文件正常工作,**后缀确实必须是.mjs **,这还不够强调(Windows,节点10.15.3) (3认同)
  • 您确定5号吗?我给人的印象是.mjs并不是将其表示为实验性的,而是因为模块规范没有提供一种仅通过读取代码来判断文件应使用模块加载器还是要求加载器的有效方法。 (2认同)
  • 在节点v12.6.0中工作。但遗憾地看到,这是仍处于试验阶段 (2认同)

Joa*_*sen 26

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

与我之前所做的比较:

const
  Http = require('http')
  ,Fs = require('fs')
  ,Path = require('path')
  ,Readline = require('readline')
  ,Os = require('os')
Run Code Online (Sandbox Code Playgroud)

只要是package.json文件中的以下字段,即可导入是ECMAScript模块的任何模块,而无需使用.mjs扩展名:

"type": "module"
Run Code Online (Sandbox Code Playgroud)

因此,请确保将package.json文件放在与要创建的模块相同的文件夹中。

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

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

当然,请不要忘记使用模块导入来实际运行脚本是必需的(在v13.2之后不再需要):

node --experimental-modules my-script-that-use-import.js
Run Code Online (Sandbox Code Playgroud)

而且父文件夹需要该package.json文件才能使该脚本不抱怨导入语法:

{
  "type": "module"
}
Run Code Online (Sandbox Code Playgroud)

如果您要使用的模块尚未更新为支持使用import语法导入,则除了使用require之外,您别无选择(但是上面的解决方案没有问题)。

  • 从 Node v.13 开始,不需要实验标志。https://nodejs.org/api/esm.html (3认同)
  • 如果您仔细阅读我最初的评论,您可以看到以下文字“无需调整即可导入”。这意味着没有标志也没有配置。这是我评论的要点。 (2认同)
  • @AlexeySh。好吧,对我写的东西发表评论是一件很奇怪的事情,因为我没有说其他任何东西。 (2认同)

Zar*_*doz 19

如果您在服务器端使用模块系统,则根本不需要使用Babel.要在NodeJS中使用模块,请确保:

  1. 使用支持--experimental-modules标志的节点版本
  2. 然后必须将您的.js文件重命名为.mjs

而已.

然而,这是一个很大的问题,而你的闪亮纯ES6代码将在NodeJS等环境中运行(编写9.5.0),你仍然会有疯狂的疯狂只是为了测试.另外请记住,Ecma已经声明Javascript的发布周期会更快,更新的功能会定期发布.虽然对于像NodeJS这样的单一环境来说这不会有问题,但它对于浏览器环境来说却略有不同.显而易见的是,测试框架在追赶方面有很多工作要做.您仍然需要转换测试框架.我建议用jest.

还要注意捆绑框架,你会遇到问题

  • 你有这方面的文件吗? (2认同)

Los*_*Don 13

你可以试试esm.

以下是一些介绍:https: //www.npmjs.com/package/esm


B12*_*ter 11

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

官方文档状态

如果最近的父 package.json 包含 "type": "module",.js 和无扩展文件的 import 语句将被视为 ES 模块。

{
  "type": "module",
  "main": "./src/index.js"
}
Run Code Online (Sandbox Code Playgroud)

(当然,您仍然需要--experimental-modules在启动应用程序时提供标志。)


cod*_*ent 8

回到Jonathan002的原始问题

"......什么版本支持新的ES6导入语句?"

根据Axel Rauschmayer博士文章,计划在Node.js 10.x LTS中默认支持它(没有实验命令行标志).根据node.js的发布计划,因为它是在2018年3月29日,它可能在2018年4月之后可用,而它的LTS将在2018年10月开始.

  • @RanaTallal节点10 api仍然显示标志 (5认同)
  • 它已被添加:? (2认同)

Dmi*_*nov 8

https://www.npmjs.com/package/babel-register

// this is to allow ES6 export syntax
// to be properly read and processed by node.js application
require('babel-register')({
  presets: [
    'env',
  ],
});

// after that any line you add below that has typical es6 export syntax 
// will work just fine

const utils = require('../../utils.js');
const availableMixins = require('../../../src/lib/mixins/index.js');
Run Code Online (Sandbox Code Playgroud)

下面是mixins/index.js的定义

export { default as FormValidationMixin } from './form-validation'; // eslint-disable-line import/prefer-default-export
Run Code Online (Sandbox Code Playgroud)

在我的node.js CLI应用程序中运行得很好.


zlo*_*ctb 7

  "devDependencies": {
    "@babel/core": "^7.2.0",
    "@babel/preset-env": "^7.2.0",
    "@babel/register": "^7.0.0"
  }
Run Code Online (Sandbox Code Playgroud)

.babelrc

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

入口点node.js应用

require("@babel/register")({})

// Import the rest of our application.
module.exports = require('./index.js')
Run Code Online (Sandbox Code Playgroud)

链接如何在Node.JS中启用ES6导入 https://timonweb.com/posts/how-to-enable-es6-imports-in-nodejs/


unf*_*res 5

我不知道这是否适用于您的情况,但我正在运行Express.js服务器:

nodemon --inspect ./index.js --exec babel-node --presets es2015,stage-2
Run Code Online (Sandbox Code Playgroud)

这使我能够导入和使用扩展运算符,即使我只使用 Node.js 版本 8。

你需要安装 babel-cli、babel-preset-es2015 和 babel-preset-stage-2 来做我正在做的事情。