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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45854169/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 18:27:23  来源:igfitidea点击:

How can I use an es6 import in node?

node.jses6-modules

提问by Jonathan002

I'm trying to get the hang of ES6imports in node and am trying to use the syntax provided in this example:

我正在尝试了解ES6节点中的导入,并尝试使用本示例中提供的语法:

Cheatsheet Link

备忘单链接

I'm looking through the support table, but was not able to find what version supports the new import statements (I tried looking for the text import/require) I'm currently running node 8.1.2 and also believe that since the cheatsheet is referring to .js files it should work with .js files.

我正在查看支持表,但无法找到支持新导入语句的版本(我尝试查找文本导入/要求)我目前正在运行节点 8.1.2 并且也相信因为备忘单是引用 .js 文件,它应该与 .js 文件一起使用。

As I run the code (taken from cheatsheet's 1st example):

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

import { square, diag } from 'lib';

I get the error:

我收到错误:

SyntaxError: Unexpected token import.

Reference to lib I'm trying to import:

对我尝试导入的 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));
}

What am I missing and how can I get nodeto recognize my importstatement?

我错过了什么,我怎样node才能认出我的import陈述?

采纳答案by tbking

Node.js has included experimental support for ES6 support. Read more about here: https://nodejs.org/docs/latest-v13.x/api/esm.html#esm_enabling.

Node.js 已包含对 ES6 支持的实验性支持。在此处阅读更多信息:https: //nodejs.org/docs/latest-v13.x/api/esm.html#esm_enabling

TLDR;

TLDR;

Node >= v13

节点 >= v13

It's very simple in Node 13 and above. You need to either:

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

  • Save the file with .mjsextension, or
  • Add { "type": "module" }in the nearest package.json.
  • 使用.mjs扩展名保存文件,或
  • 添加{ "type": "module" }最近的package.json.

You only need to do one of the above to be able to use ES modules.

您只需要执行上述其中一项即可使用 ES 模块。

Node <= v12

节点 <= v12

If you are using Node version 8-12, Save the file with ES6 modules with .mjsextension and run it like:

如果您使用的是 Node 版本 8-12,请使用带有.mjs扩展名的ES6 模块保存文件并运行它:

node --experimental-modules my-app.mjs

回答by Seunope

You can also use npm package called esmwhich allows you to use ES6 modules in node. It needs no configuration. With esm you will be able to use export/import in your JS files.

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

Run the following command on your terminal

在终端上运行以下命令

yarn add esm 

or

或者

npm install esm

After that, you need to require this package when starting your server with node. For example if your node server runs index.js file, you would use the command

之后,在使用 node.js 启动服务器时需要这个包。例如,如果您的节点服务器运行 index.js 文件,您将使用命令

node -r esm index.js

You can also add it in your package.json file like this

你也可以像这样将它添加到你的 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"
  },

}

Then run this command from the terminal to start your node server

然后从终端运行此命令以启动您的节点服务器

npm start

Check this linkfor more details

查看此链接了解更多详情

回答by Manohar Reddy Poreddy

Wasted about 3 hours.

浪费了大约3个小时。

I just wanted to use the importand exportin js files.

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

Everyone says not possible. But, as of May 2018, it's possible to use above in plain node.js, without any modules like babel, etc.

大家都说不可能。但是,截至 2018 年 5 月,可以在普通 node.js 中使用上面的内容,而无需像 babel 等任何模块。

Here is a simple way to do it.

这是一个简单的方法。

Create below files, run and see output for yourself.

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

Also don't forget to see Explanationbelow.

也不要忘记看Explanation下面。

myfile.mjs

我的文件.mjs

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

export default myFunc;

index.mjs

索引.mjs

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

myFunc();

run

node  --experimental-modules  index.mjs

output

输出

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

Hello from myFunc

Explanation:

解释:

  1. Since it is experimental modules, .js files are named .mjs files
  2. While running you will add --experimental-modulesto the node index.mjs
  3. While running with experimental modules in the output you will see: "(node:12020) ExperimentalWarning: The ESM module loader is experimental. "
  4. I have the current release of node js, so if I run node --version, it gives me "v10.3.0", though the LTE/stable/recommended version is 8.11.2 LTS.
  5. Someday in the future, you could use .js instead of .mjs, as the features become stable instead of Experimental.
  6. More on experimental features, see: https://nodejs.org/api/esm.html
  1. 由于是实验模块,.js 文件被命名为 .mjs 文件
  2. 运行时,您将添加--experimental-modulesnode index.mjs
  3. 在输出中使用实验模块运行时,您将看到:“(节点:12020)实验警告:ESM 模块加载器是实验性的。”
  4. 我有 node js 的当前版本,所以如果我运行node --version,它会给我“v10.3.0”,尽管 LTE/stable/recommended 版本是 8.11.2 LTS。
  5. 在未来的某一天,你可以使用 .js 而不是 .mjs,因为特性变得稳定而不是实验性。
  6. 有关实验性功能的更多信息,请参阅:https: //nodejs.org/api/esm.html

Hope that helped.

希望有所帮助。

 

 

回答by Joakim L. Christiansen

Using Node v12.2.0 I can import all standard modules like this:

使用 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'

Versus what I did before:

与我之前所做的相比:

const
  Http = require('http')
  ,Fs = require('fs')
  ,Path = require('path')
  ,Readline = require('readline')
  ,Os = require('os')

Any module that is an ECMAScript module can be imported without having to use an .mjs extension as long as it has this field in its package.json file:

任何属于 ECMAScript 模块的模块都可以导入而无需使用 .mjs 扩展名,只要它的 package.json 文件中有此字段:

"type": "module"

So make sure you put such a package.json file in the same folder as the module you're making.

因此,请确保将这样的 package.json 文件与您正在制作的模块放在同一文件夹中。

And to import modules not updated with ECMAScript module support you can do like this:

要导入未使用 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')

And of course, do not forget that this is needed to actually run a script using module imports (not needed after v13.2):

当然,不要忘记这需要使用模块导入实际运行脚本(v13.2 之后不需要):

node --experimental-modules my-script-that-use-import.js

And that the parent folder needs this package.json file for that script to not complain about the import syntax:

并且父文件夹需要这个 package.json 文件来让脚本不抱怨导入语法:

{
  "type": "module"
}

If the module you want to use has not been updated to support being imported using the import syntax then you have no other choice than using require (but with my solution above that is not a problem).

如果您要使用的模块尚未更新以支持使用导入语法进行导入,那么您除了使用 require 之外别无选择(但对于我上面的解决方案,这不是问题)。

I also want to share this piece of code which implements the missing __filenameand __dirnameconstants in modules:

我还想分享这段代码,它实现了模块中的缺失__filename__dirname常量:

import {fileURLToPath} from 'url'
import {dirname} from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

回答by Zardoz

If you are using the modules system on the server side, you do not need to use Babel at all. To use modules in NodeJS ensure that:

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

  1. Use a version of node that supports the --experimental-modulesflag
  2. Your .jsfiles must then be renamed to .mjs
  1. 使用支持--experimental-modules标志的节点版本
  2. 然后必须将您的.js文件重命名为.mjs

That's it.

就是这样。

However and this is a big however, while your shinny pure ES6 code will run in an environment like NodeJS (at writing 9.5.0) you will still have the craziness of transpilling just to test. Also bear in mind that Ecma has stated that release cycles for Javascript are going to be faster, with newer features delivered on a more regular basis. Whilst this will be no problems for single environments like NodeJS, its a slightly different proposition for browser environments. What is clear is that testing frameworks have a lot to do in catching up. You will still need to probably transpile for testing frameworks. I'd suggest using jest.

然而,这是一个很大的问题,虽然您的纯 ES6 代码将在 NodeJS 之类的环境中运行(编写 9.5.0),但您仍然会为了测试而疯狂地进行转译。还要记住,Ecma 表示 Javascript 的发布周期将会更快,更新的功能会更定期地交付。虽然这对于像 NodeJS 这样的单一环境没有问题,但它对于浏览器环境的主张略有不同。很明显,测试框架在追赶方面还有很多工作要做。您可能仍然需要为测试框架进行转换。我建议使用jest。

Also be aware of bundling frameworks, you will be running into problems there

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

回答by Losses Don

You may try esm.

你可以试试esm

Here are some introduction: https://www.npmjs.com/package/esm

这里有一些介绍:https: //www.npmjs.com/package/esm

回答by zloctb

  "devDependencies": {
    "@babel/core": "^7.2.0",
    "@babel/preset-env": "^7.2.0",
    "@babel/register": "^7.0.0"
  }

.babelrc

.babelrc

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

entry point node.js app

入口点 node.js 应用程序

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

// Import the rest of our application.
module.exports = require('./index.js')

Link How To Enable ES6 Imports in Node.JS https://timonweb.com/posts/how-to-enable-es6-imports-in-nodejs/

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

回答by codeful.element

Back to Jonathan002's original question about

回到Jonathan002关于 的原始问题

"... what version supports the new ES6 import statements?"

“……什么版本支持新的 ES6 导入语句?”

based on the article by Dr. Axel Rauschmayer, there is a plan to have it supported by default (without the experimental command line flag) in Node.js 10.x LTS. According to node.js's release planas it is on 3/29, 2018, it's likely to become available after Apr 2018,while LTS of it will begin on October 2018.

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

回答by DmitrySemenov

solution

解决方案

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

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');

below is definition of mixins/index.js

下面是 mixins/index.js 的定义

export { default as FormValidationMixin } from './form-validation'; // eslint-disable-line import/prefer-default-export

that worked just fine inside my node.js CLI app.

在我的 node.js CLI 应用程序中运行良好。

回答by B12Toaster

Using the .mjsextension (as suggested in the accepted answer) in order to enable ECMAScript modules works, however, with Node.js v12, you can also enable this feature globally in your package.json.

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

The official docs state:

官方的文档说明

import statements of .js and extensionless files are treated as ES modules if the nearest parent package.json contains "type": "module".

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

{
  "type": "module",
  "main": "./src/index.js"
}

(Of course you still have to provide the flag --experimental-moduleswhen starting your app).

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