使用节点。js需要vs. ES6导入/导出。

时间:2021-08-09 15:45:23

In a project I'm collaborating on, we have two choices on which module system we can use:

在我正在合作的一个项目中,我们有两个选择,我们可以使用哪个模块系统:

  1. Importing modules using require, and exporting using module.exports and exports.foo.
  2. 使用require导入模块,使用模块导出模块。出口和exports.foo。
  3. Importing modules using ES6 import, and exporting using ES6 export
  4. 使用ES6导入模块导入,使用ES6导出模块导出

Are there any performance benefits to using one over the other? Is there anything else that we should know if we were to use ES6 modules over Node ones?

使用其中一种有什么性能优势吗?如果我们要使用ES6模块而不是节点,我们还应该知道什么?

7 个解决方案

#1


462  

Are there any performance benefits to using one over the other?

使用其中一种有什么性能优势吗?

Keep in mind that there is no JavaScript engine yet that natively supports ES6 modules. You said yourself that you are using Babel. Babel converts import and export declaration to CommonJS (require/module.exports) by default anyway. So even if you use ES6 module syntax, you will be using CommonJS under the hood if you run the code in Node.

请记住,目前还没有本地支持ES6模块的JavaScript引擎。你说你在用巴别塔。Babel默认将导入和导出声明转换为CommonJS (require/modu .exports)。因此,即使您使用ES6模块语法,如果您在节点中运行代码,您也将在hood中使用CommonJS。

There are technical difference between CommonJS and ES6 modules, e.g. CommonJS allows you to load modules dynamically. ES6 doesn't allow this, but there is an API in development for that.

CommonJS和ES6模块之间存在技术差异,例如,CommonJS允许动态加载模块。ES6不允许这样,但是有一个API正在开发中。

Since ES6 modules are part of the standard, I would use them.

由于ES6模块是标准的一部分,我将使用它们。

#2


93  

There are several usage / capabilities you might want to consider:

您可能需要考虑以下几种用法/功能:

Require:

要求:

  • You can have dynamic loading where the loaded module name isn't predefined /static, or where you conditionally load a module only if it's "truly required" (depending on certain code flow).
  • 您可以动态加载,加载的模块名不是预定义的/静态的,或者只有在“真正需要”时才有条件地加载模块(取决于特定的代码流)。
  • Loading is synchronous. That means if you have multiple requires, they are loaded and processed one by one.
  • 加载是同步的。这意味着如果您有多个需求,它们将被逐一加载和处理。

ES6 Imports:

ES6进口:

  • You can use named imports to selectively load only the pieces you need. That can save memory.
  • 您可以使用命名导入来选择性地加载您需要的部分。可以节省内存。
  • Import can be asynchronous (and in current ES6 Module Loader, it in fact is) and can perform a little better.
  • 导入可以是异步的(在当前的ES6模块加载器中,实际上是异步的),并且可以执行得更好。

Also, the Require module system isn't standard based. It's is highly unlikely to become standard now that ES6 modules exist. In the future there will be native support for ES6 Modules in various implementations which will be advantageous in terms of performance.

而且,Require模块系统不是基于标准的。由于ES6模块的存在,它不太可能成为标准。在未来,在各种实现中会有对ES6模块的本机支持,这在性能上是有利的。

#3


30  

The main advantages are syntactic:

主要的优点是句法上的:

  • More declarative/compact syntax
  • 更多的声明/紧凑语法
  • ES6 modules will basically make UMD (Universal Module Definition) obsolete - essentially removes the schism between CommonJS and AMD (server vs browser).
  • ES6模块将基本使UMD(通用模块定义)过时——基本上消除了CommonJS和AMD(服务器vs浏览器)之间的分歧。

You are unlikely to see any performance benefits with ES6 modules. You will still need an extra library to bundle the modules, even when there is full support for ES6 features in the browser.

您不太可能看到ES6模块的任何性能优势。您仍然需要一个额外的库来捆绑这些模块,即使在浏览器中完全支持ES6功能时也是如此。

#4


22  

Are there any performance benefits to using one over the other?

使用其中一种有什么性能优势吗?

The current answer is no, because none of the current browser engines implements import/export from the ES6 standard.

目前的答案是否定的,因为当前的浏览器引擎都没有实现从ES6标准的导入/导出。

Some comparison charts http://kangax.github.io/compat-table/es6/ don't take this into account, so when you see almost all greens for Chrome, just be careful. import keyword from ES6 hasn't been taken into account.

一些比较图表http://kangax.github。io/compat-table/es6/不要考虑这个,所以当你看到几乎所有的绿色都是Chrome时,要小心。尚未考虑从ES6导入关键字。

In other words, current browser engines including V8 cannot import new JavaScript file from the main JavaScript file via any JavaScript directive.

换句话说,包括V8在内的当前浏览器引擎无法通过任何JavaScript指令从主JavaScript文件导入新的JavaScript文件。

( We may be still just a few bugs away or years away until V8 implements that according to the ES6 specification. )

(在V8根据ES6规范实现这个功能之前,我们可能还会有一些bug,或者还需要几年的时间。)

This document is what we need, and this document is what we must obey.

这个文件是我们需要的,这个文件是我们必须遵守的。

And the ES6 standard said that the module dependencies should be there before we read the module like in the programming language C, where we had (headers) .h files.

ES6标准说,在我们读模块之前,模块依赖项应该在那里,就像在编程语言C中,我们有。h文件。

This is a good and well-tested structure, and I am sure the experts that created the ES6 standard had that in mind.

这是一种经过良好测试的良好结构,我相信创建ES6标准的专家们已经考虑到了这一点。

This is what enables Webpack or other package bundlers to optimize the bundle in some special cases, and reduce some dependencies from the bundle that are not needed. But in cases we have perfect dependencies this will never happen.

这使得Webpack或其他包bundlers能够在某些特殊的情况下优化bundle,并减少不需要的bundle的一些依赖项。但在我们有完美的依赖关系的情况下,这种情况永远不会发生。

It will need some time until import/export native support goes live, and the require keyword will not go anywhere for a long time.

导入/导出本地支持需要一段时间,而且require关键字在很长一段时间内不会出现在任何地方。

What is require?

要求是什么?

This is node.js way to load modules. ( https://github.com/nodejs/node )

这是节点。js加载模块的方式。(https://github.com/nodejs/node)

Node uses system-level methods to read files. You basically rely on that when using require. require will end in some system call like uv_fs_open (depends on the end system, Linux, Mac, Windows) to load JavaScript file/module.

Node使用系统级方法来读取文件。在使用require时,您基本上依赖它。require将在一些系统调用中结束,比如uv_fs_open(取决于最终系统、Linux、Mac、Windows),以加载JavaScript文件/模块。

To check that this is true, try to use Babel.js, and you will see that the import keyword will be converted into require.

要验证这是真的,请使用Babel。js,您将看到import关键字将被转换成需要。

使用节点。js需要vs. ES6导入/导出。

#5


17  

Using ES6 modules can be useful for 'tree shaking'; i.e. enabling Webpack 2, Rollup (or other bundlers) to identify code paths that are not used/imported, and therefore don't make it into the resulting bundle. This can significantly reduce its file size by eliminating code you'll never need, but with CommonJS is bundled by default because Webpack et al have no way of knowing whether it's needed.

使用ES6模块可以用于“树摇动”;例如,启用Webpack 2、Rollup(或其他bundlers)来标识未使用/导入的代码路径,因此不要将其放入结果包中。这可以通过消除您永远不需要的代码来显著减少文件的大小,但是使用CommonJS是默认绑定的,因为Webpack等人没有办法知道它是否需要。

This is done using static analysis of the code path.

这是使用代码路径的静态分析完成的。

For example, using:

例如,使用:

import { somePart } 'of/a/package';

... gives the bundler a hint that package.anotherPart isn't required (if it's not imported, it can't be used- right?), so it won't bother bundling it.

…给了bundler一个提示。另一个部分不是必需的(如果它不是导入的,它就不能使用——对吗?),所以它不会麻烦地打包它。

To enable this for Webpack 2, you need to ensure that your transpiler isn't spitting out CommonJS modules. If you're using the es2015 plug-in with babel, you can disable it in your .babelrc like so:

要为Webpack 2启用此功能,您需要确保您的传输器没有输出CommonJS模块。如果您正在使用带有babel的es2015插件,您可以在.babelrc中禁用它,如下所示:

{
  "presets": [
    ["es2015", { modules: false }],
  ]
}

Rollup and others may work differently - view the docs if you're interested.

Rollup和其他功能可能会有所不同——如果您感兴趣,可以查看文档。

#6


4  

When it comes to async or maybe lazy loading, then import () is much more powerful. See when we require component in async manner, then only we import it in some async manner as in const variable.

当涉及到异步或延迟加载时,import()功能要强大得多。当我们以异步方式要求组件时,您将看到,只有我们以某种异步方式导入组件,就像在const变量中一样。

const module = await import('./module.js');

Or if you want to use require() then,

或者如果你想用require()

const converter = require('./converter');

Thing is import() is actually async in nature. As mentioned by neehar venugopal in ReactConf, you can use it to dynamically load components.

导入()本质上是异步的。正如在反应物中neehar venugopal提到的,你可以用它来动态加载组件。

Also it is way better when it comes to Routing. That is the one special thing that makes network log to download necessary part when user connects to specific website to its specific component. eg. login page before dashboard would'nt download all components of dashboard. Because what is needed current i.e. login component, that only will be downloaded.

同样,当谈到路由时,它也会更好。当用户将特定的网站连接到特定的组件时,这是使网络日志下载成为必要部分的一个特殊因素。如。仪表板之前的登录页面不会下载仪表板的所有组件。因为需要的是当前即登录组件,所以只会被下载。

NOTE - If you are developing a node.js project, then you have to strictly use require() as node will throw exception error as invalid token 'import' if you will use import . So node does not support import statements

注意——如果您正在开发一个节点。然后,您必须严格地使用require(),因为如果使用import,节点将抛出异常错误,作为无效的令牌'import'。因此,node不支持import语句。

See this for more clearance where to use async imports - https://www.youtube.com/watch?v=bb6RCrDaxhw

有关使用异步导入的更多信息,请参见本文——https://www.youtube.com/watch?v=bb6RCrDaxhw

#7


3  

I personally use import because, we can import the required methods, members by using import.

我个人使用import是因为,我们可以通过import来导入所需的方法,成员。

import {foo, bar} from "dep";

FileName: dep.js

文件名:dep.js

export foo function(){};
export const bar = 22

Credit goes to Paul Shan. More info.

贷款给了单保罗。更多信息。

#1


462  

Are there any performance benefits to using one over the other?

使用其中一种有什么性能优势吗?

Keep in mind that there is no JavaScript engine yet that natively supports ES6 modules. You said yourself that you are using Babel. Babel converts import and export declaration to CommonJS (require/module.exports) by default anyway. So even if you use ES6 module syntax, you will be using CommonJS under the hood if you run the code in Node.

请记住,目前还没有本地支持ES6模块的JavaScript引擎。你说你在用巴别塔。Babel默认将导入和导出声明转换为CommonJS (require/modu .exports)。因此,即使您使用ES6模块语法,如果您在节点中运行代码,您也将在hood中使用CommonJS。

There are technical difference between CommonJS and ES6 modules, e.g. CommonJS allows you to load modules dynamically. ES6 doesn't allow this, but there is an API in development for that.

CommonJS和ES6模块之间存在技术差异,例如,CommonJS允许动态加载模块。ES6不允许这样,但是有一个API正在开发中。

Since ES6 modules are part of the standard, I would use them.

由于ES6模块是标准的一部分,我将使用它们。

#2


93  

There are several usage / capabilities you might want to consider:

您可能需要考虑以下几种用法/功能:

Require:

要求:

  • You can have dynamic loading where the loaded module name isn't predefined /static, or where you conditionally load a module only if it's "truly required" (depending on certain code flow).
  • 您可以动态加载,加载的模块名不是预定义的/静态的,或者只有在“真正需要”时才有条件地加载模块(取决于特定的代码流)。
  • Loading is synchronous. That means if you have multiple requires, they are loaded and processed one by one.
  • 加载是同步的。这意味着如果您有多个需求,它们将被逐一加载和处理。

ES6 Imports:

ES6进口:

  • You can use named imports to selectively load only the pieces you need. That can save memory.
  • 您可以使用命名导入来选择性地加载您需要的部分。可以节省内存。
  • Import can be asynchronous (and in current ES6 Module Loader, it in fact is) and can perform a little better.
  • 导入可以是异步的(在当前的ES6模块加载器中,实际上是异步的),并且可以执行得更好。

Also, the Require module system isn't standard based. It's is highly unlikely to become standard now that ES6 modules exist. In the future there will be native support for ES6 Modules in various implementations which will be advantageous in terms of performance.

而且,Require模块系统不是基于标准的。由于ES6模块的存在,它不太可能成为标准。在未来,在各种实现中会有对ES6模块的本机支持,这在性能上是有利的。

#3


30  

The main advantages are syntactic:

主要的优点是句法上的:

  • More declarative/compact syntax
  • 更多的声明/紧凑语法
  • ES6 modules will basically make UMD (Universal Module Definition) obsolete - essentially removes the schism between CommonJS and AMD (server vs browser).
  • ES6模块将基本使UMD(通用模块定义)过时——基本上消除了CommonJS和AMD(服务器vs浏览器)之间的分歧。

You are unlikely to see any performance benefits with ES6 modules. You will still need an extra library to bundle the modules, even when there is full support for ES6 features in the browser.

您不太可能看到ES6模块的任何性能优势。您仍然需要一个额外的库来捆绑这些模块,即使在浏览器中完全支持ES6功能时也是如此。

#4


22  

Are there any performance benefits to using one over the other?

使用其中一种有什么性能优势吗?

The current answer is no, because none of the current browser engines implements import/export from the ES6 standard.

目前的答案是否定的,因为当前的浏览器引擎都没有实现从ES6标准的导入/导出。

Some comparison charts http://kangax.github.io/compat-table/es6/ don't take this into account, so when you see almost all greens for Chrome, just be careful. import keyword from ES6 hasn't been taken into account.

一些比较图表http://kangax.github。io/compat-table/es6/不要考虑这个,所以当你看到几乎所有的绿色都是Chrome时,要小心。尚未考虑从ES6导入关键字。

In other words, current browser engines including V8 cannot import new JavaScript file from the main JavaScript file via any JavaScript directive.

换句话说,包括V8在内的当前浏览器引擎无法通过任何JavaScript指令从主JavaScript文件导入新的JavaScript文件。

( We may be still just a few bugs away or years away until V8 implements that according to the ES6 specification. )

(在V8根据ES6规范实现这个功能之前,我们可能还会有一些bug,或者还需要几年的时间。)

This document is what we need, and this document is what we must obey.

这个文件是我们需要的,这个文件是我们必须遵守的。

And the ES6 standard said that the module dependencies should be there before we read the module like in the programming language C, where we had (headers) .h files.

ES6标准说,在我们读模块之前,模块依赖项应该在那里,就像在编程语言C中,我们有。h文件。

This is a good and well-tested structure, and I am sure the experts that created the ES6 standard had that in mind.

这是一种经过良好测试的良好结构,我相信创建ES6标准的专家们已经考虑到了这一点。

This is what enables Webpack or other package bundlers to optimize the bundle in some special cases, and reduce some dependencies from the bundle that are not needed. But in cases we have perfect dependencies this will never happen.

这使得Webpack或其他包bundlers能够在某些特殊的情况下优化bundle,并减少不需要的bundle的一些依赖项。但在我们有完美的依赖关系的情况下,这种情况永远不会发生。

It will need some time until import/export native support goes live, and the require keyword will not go anywhere for a long time.

导入/导出本地支持需要一段时间,而且require关键字在很长一段时间内不会出现在任何地方。

What is require?

要求是什么?

This is node.js way to load modules. ( https://github.com/nodejs/node )

这是节点。js加载模块的方式。(https://github.com/nodejs/node)

Node uses system-level methods to read files. You basically rely on that when using require. require will end in some system call like uv_fs_open (depends on the end system, Linux, Mac, Windows) to load JavaScript file/module.

Node使用系统级方法来读取文件。在使用require时,您基本上依赖它。require将在一些系统调用中结束,比如uv_fs_open(取决于最终系统、Linux、Mac、Windows),以加载JavaScript文件/模块。

To check that this is true, try to use Babel.js, and you will see that the import keyword will be converted into require.

要验证这是真的,请使用Babel。js,您将看到import关键字将被转换成需要。

使用节点。js需要vs. ES6导入/导出。

#5


17  

Using ES6 modules can be useful for 'tree shaking'; i.e. enabling Webpack 2, Rollup (or other bundlers) to identify code paths that are not used/imported, and therefore don't make it into the resulting bundle. This can significantly reduce its file size by eliminating code you'll never need, but with CommonJS is bundled by default because Webpack et al have no way of knowing whether it's needed.

使用ES6模块可以用于“树摇动”;例如,启用Webpack 2、Rollup(或其他bundlers)来标识未使用/导入的代码路径,因此不要将其放入结果包中。这可以通过消除您永远不需要的代码来显著减少文件的大小,但是使用CommonJS是默认绑定的,因为Webpack等人没有办法知道它是否需要。

This is done using static analysis of the code path.

这是使用代码路径的静态分析完成的。

For example, using:

例如,使用:

import { somePart } 'of/a/package';

... gives the bundler a hint that package.anotherPart isn't required (if it's not imported, it can't be used- right?), so it won't bother bundling it.

…给了bundler一个提示。另一个部分不是必需的(如果它不是导入的,它就不能使用——对吗?),所以它不会麻烦地打包它。

To enable this for Webpack 2, you need to ensure that your transpiler isn't spitting out CommonJS modules. If you're using the es2015 plug-in with babel, you can disable it in your .babelrc like so:

要为Webpack 2启用此功能,您需要确保您的传输器没有输出CommonJS模块。如果您正在使用带有babel的es2015插件,您可以在.babelrc中禁用它,如下所示:

{
  "presets": [
    ["es2015", { modules: false }],
  ]
}

Rollup and others may work differently - view the docs if you're interested.

Rollup和其他功能可能会有所不同——如果您感兴趣,可以查看文档。

#6


4  

When it comes to async or maybe lazy loading, then import () is much more powerful. See when we require component in async manner, then only we import it in some async manner as in const variable.

当涉及到异步或延迟加载时,import()功能要强大得多。当我们以异步方式要求组件时,您将看到,只有我们以某种异步方式导入组件,就像在const变量中一样。

const module = await import('./module.js');

Or if you want to use require() then,

或者如果你想用require()

const converter = require('./converter');

Thing is import() is actually async in nature. As mentioned by neehar venugopal in ReactConf, you can use it to dynamically load components.

导入()本质上是异步的。正如在反应物中neehar venugopal提到的,你可以用它来动态加载组件。

Also it is way better when it comes to Routing. That is the one special thing that makes network log to download necessary part when user connects to specific website to its specific component. eg. login page before dashboard would'nt download all components of dashboard. Because what is needed current i.e. login component, that only will be downloaded.

同样,当谈到路由时,它也会更好。当用户将特定的网站连接到特定的组件时,这是使网络日志下载成为必要部分的一个特殊因素。如。仪表板之前的登录页面不会下载仪表板的所有组件。因为需要的是当前即登录组件,所以只会被下载。

NOTE - If you are developing a node.js project, then you have to strictly use require() as node will throw exception error as invalid token 'import' if you will use import . So node does not support import statements

注意——如果您正在开发一个节点。然后,您必须严格地使用require(),因为如果使用import,节点将抛出异常错误,作为无效的令牌'import'。因此,node不支持import语句。

See this for more clearance where to use async imports - https://www.youtube.com/watch?v=bb6RCrDaxhw

有关使用异步导入的更多信息,请参见本文——https://www.youtube.com/watch?v=bb6RCrDaxhw

#7


3  

I personally use import because, we can import the required methods, members by using import.

我个人使用import是因为,我们可以通过import来导入所需的方法,成员。

import {foo, bar} from "dep";

FileName: dep.js

文件名:dep.js

export foo function(){};
export const bar = 22

Credit goes to Paul Shan. More info.

贷款给了单保罗。更多信息。