使用Node.js require与ES6导入/导出

本文翻译自:Using Node.js require vs. ES6 import/export

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 . 导入使用模块require ,并利用出口module.exportsexports.foo
  2. Importing modules using ES6 import , and exporting using ES6 export 使用ES6 import导入模块,并使用ES6 export

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? 如果要在Node模块上使用ES6模块,还有其他什么应该知道的吗?


#1楼

参考:https://stackoom.com/question/27Ykh/使用Node-js-require与ES-导入-导出


#2楼

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(服务器与浏览器)之间的分裂。

You are unlikely to see any performance benefits with ES6 modules. 您不太可能看到ES6模块的任何性能优势。 You will still need an extra library to bundle the modules, even when there is full support for ES6 features in the browser. 即使浏览器完全支持ES6功能,您仍将需要一个额外的库来捆绑模块。


#3楼

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). 您可以在未预定义的模块名称/ static的情况下进行动态加载,或者仅在“确实需要”模块时才有条件地加载模块(取决于某些代码流)。
  • Loading is synchronous. 加载是同步的。 That means if you have multiple require s, they are loaded and processed one by one. 这意味着,如果您有多个require ,它们将被一个接一个地加载和处理。

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 Module Loader中),并且可以执行得更好。

Also, the Require module system isn't standard based. 另外,Require模块系统也不基于标准。 It's is highly unlikely to become standard now that ES6 modules exist. 由于存在ES6模块,因此极不可能成为标准。 In the future there will be native support for ES6 Modules in various implementations which will be advantageous in terms of performance. 将来,将在各种实现中对ES6模块提供本机支持,这将在性能方面带来优势。


#4楼

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. 请记住,还没有JavaScript引擎本身支持ES6模块。 You said yourself that you are using Babel. 您说自己正在使用Babel。 Babel converts import and export declaration to CommonJS ( require / module.exports ) by default anyway. 无论如何, module.exports缺省情况下module.exportsimportexport声明转换为CommonJS( require / module.exports )。 So even if you use ES6 module syntax, you will be using CommonJS under the hood if you run the code in Node. 因此,即使您使用ES6模块语法,但如果在Node中运行代码,您也将在后台使用CommonJS。

There are technical differences between CommonJS and ES6 modules, eg CommonJS allows you to load modules dynamically. CommonJS和ES6模块之间存在技术差异,例如,CommonJS允许您动态加载模块。 ES6 doesn't allow this, but there is an API in development for that . ES6不允许这样做, 但是正在为此开发一个API

Since ES6 modules are part of the standard, I would use them. 由于ES6模块是标准的一部分,因此我将使用它们。


#5楼

Using ES6 modules can be useful for 'tree shaking'; 使用ES6模块对于“摇树”很有用; ie 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. 例如,启用Webpack 2,汇总(或其他捆绑程序)以标识未使用/导入的代码路径,因此不要将其放入生成的捆绑程序中。 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. 通过消除不需要的代码,可以大大减少文件的大小,但是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. ……给捆绑程序一个提示,即不需要package.anotherPart (如果未导入,则不能使用它-对吗?),因此不会打扰它。

To enable this for Webpack 2, you need to ensure that your transpiler isn't spitting out CommonJS modules. 要为Webpack 2启用此功能,您需要确保您的编译器不会吐出CommonJS模块。 If you're using the es2015 plug-in with babel, you can disable it in your .babelrc like so: 如果您将es2015插件与babel一起使用,则可以在.babelrc其禁用, .babelrc所示:

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

Rollup and others may work differently - view the docs if you're interested. 汇总和其他工具的工作方式可能有所不同-如果您有兴趣,请查看文档。


#6楼

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标准import/export

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. 一些比较表http://kangax.github.io/compat-table/es6/没有考虑到这一点,因此当您看到Chrome的几乎所有绿色时,请小心。 import keyword from ES6 hasn't been taken into account. 未考虑来自ES6的import关键字。

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规范实现该功能为止,我们距离我们可能只有几步之遥,也可能只有年之遥。)

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. 这使Webpack或其他程序包捆绑器可以在某些特殊情况下优化该程序包,并减少某些不必要的依赖关系。 But in cases we have perfect dependencies this will never happen. 但是,如果我们有完美的依赖关系,这将永远不会发生。

It will need some time until import/export native support goes live, and the require keyword will not go anywhere for a long time. import/export本机支持生效之前,将需要一些时间,并且require关键字很长一段时间都不会出现。

What is require ? 有什么require

This is node.js way to load modules. 这是node.js加载模块的方式。 ( https://github.com/nodejs/node ) https://github.com/nodejs/node

Node uses system-level methods to read files. Node使用系统级方法来读取文件。 You basically rely on that when using require . 在使用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. require将以uv_fs_open类的系统调用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关键字将转换为require

在此处输入图片说明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值