Javascript 使用Node.js require与ES6导入/导出
在我合作的一个项目中,我们有两种选择,可以使用哪个模块系统:Javascript 使用Node.js require与ES6导入/导出,javascript,node.js,ecmascript-6,babeljs,Javascript,Node.js,Ecmascript 6,Babeljs,在我合作的一个项目中,我们有两种选择,可以使用哪个模块系统: 使用require导入模块,使用module.exports和exports.foo导出模块 使用ES6导入模块import,使用ES6导出模块export 使用其中一种方法比使用另一种方法有什么性能优势吗?如果我们要使用ES6模块而不是节点模块,还有什么我们应该知道的吗?主要优点是语法: 更具声明性/紧凑的语法 ES6模块将基本上使UMD(通用模块定义)过时-基本上消除CommonJS和AMD(服务器与浏览器)之间的分歧 您不太
require
导入模块,使用module.exports
和exports.foo
导出模块import
,使用ES6导出模块export
使用其中一种方法比使用另一种方法有什么性能优势吗?如果我们要使用ES6模块而不是节点模块,还有什么我们应该知道的吗?主要优点是语法:
- 更具声明性/紧凑的语法
- ES6模块将基本上使UMD(通用模块定义)过时-基本上消除CommonJS和AMD(服务器与浏览器)之间的分歧
您不太可能看到ES6模块的任何性能优势。即使浏览器中完全支持ES6功能,您仍然需要一个额外的库来捆绑模块。主要优点是语法:
- 更具声明性/紧凑的语法
- ES6模块将基本上使UMD(通用模块定义)过时-基本上消除CommonJS和AMD(服务器与浏览器)之间的分歧
您不太可能看到ES6模块的任何性能优势。即使浏览器中完全支持ES6功能,您仍然需要一个额外的库来捆绑模块。您可能需要考虑以下几种用法/功能: 要求:
- 您可以在加载的模块名称不存在的地方进行动态加载 预定义/静态,或者仅在以下情况下才有条件加载模块 它是“真正需要的”(取决于特定的代码流)
- 装载是
同步的这意味着如果您有多个
s,则它们是 逐个加载和处理require
- 你可以用 命名导入,仅选择性地加载所需的工件。那可以 节省内存
- 导入可以是异步的(在当前的ES6模块加载器中,事实上是异步的),并且可以执行得更好一些
此外,Require模块系统不是基于标准的。现在ES6模块已经存在,它不太可能成为标准。将来,在各种实现中都会对ES6模块提供本机支持,这在性能方面将是有利的。您可能需要考虑以下几种用法/功能: 要求:
- 您可以在加载的模块名称不存在的地方进行动态加载 预定义/静态,或者仅在以下情况下才有条件加载模块 它是“真正需要的”(取决于特定的代码流)
- 装载是
同步的这意味着如果您有多个
s,则它们是 逐个加载和处理require
- 你可以用 命名导入,仅选择性地加载所需的工件。那可以 节省内存
- 导入可以是异步的(在当前的ES6模块加载器中,事实上是异步的),并且可以执行得更好一些
导入
和导出
声明转换为CommonJS(要求
/模块。导出
)。因此,即使您使用ES6模块语法,如果您在Node中运行代码,也将使用CommonJS
CommonJS和ES6模块之间存在技术差异,例如CommonJS允许您动态加载模块。ES6不允许这样做
因为ES6模块是标准的一部分,所以我会使用它们
更新2020 从节点v12开始,对ES模块的支持在默认情况下是启用的,但在撰写本文时仍然处于试验阶段。包含节点模块的文件必须以
.mjs
或最近的包结尾。json
文件必须包含“类型”:“模块”
。还有更多关于CommonJS和ES模块之间互操作的信息
就性能而言,新功能总是有可能没有现有功能优化得那么好。但是,由于模块文件只评估一次,因此性能方面可能会被忽略。最后,您必须运行基准测试以获得明确的答案
ES模块可以通过import()
函数动态加载。与require
不同,它返回一个承诺
使用其中一种方法比使用另一种方法有什么性能优势吗
请记住,目前还没有JavaScript引擎本机支持ES6模块。你自己说过你在用巴贝尔。默认情况下,Babel将导入
和导出
声明转换为CommonJS(要求
/模块。导出
)。因此,即使您使用ES6模块语法,如果您在Node中运行代码,也将使用CommonJS
CommonJS和ES6模块之间存在技术差异,例如CommonJS允许您动态加载模块。ES6不允许这样做
因为ES6模块是标准的一部分,所以我会使用它们
更新2020 从节点v12开始,对ES模块的支持在默认情况下是启用的,但在撰写本文时仍然处于试验阶段。包含节点模块的文件必须以
.mjs
或最近的包结尾。json
文件必须包含“类型”:“模块”
。还有更多关于CommonJS和ES模块之间互操作的信息
性能-w
import { somePart } 'of/a/package';
{
"presets": [
["es2015", { modules: false }],
]
}
import {foo, bar} from "dep";
export foo function(){};
export const bar = 22
const module = await import('./module.js');
const converter = require('./converter');
export default class Foo {}
console.log('Foo loaded');
import Foo from './foo'
// prints nothing
const Foo = require('./foo').default;
// prints "Foo loaded"
(async () => {
const FooPack = await import('./foo');
// prints "Foo loaded"
})();
import Foo from './foo'
typeof Foo; // any use case
// prints "Foo loaded"
// hello.js
function hello() {
return 'hello'
}
export default hello
// app.js
import hello from './hello'
hello() // returns hello
// hello.js
function hello1() {
return 'hello1'
}
function hello2() {
return 'hello2'
}
export { hello1, hello2 }
// app.js
import { hello1, hello2 } from './hello'
hello1() // returns hello1
hello2() // returns hello2
// hello.js
function hello() {
return 'hello'
}
module.exports = hello
// app.js
const hello = require('./hello')
hello() // returns hello
// hello.js
function hello1() {
return 'hello1'
}
function hello2() {
return 'hello2'
}
module.exports = {
hello1,
hello2
}
// app.js
const hello = require('./hello')
hello.hello1() // returns hello1
hello.hello2() // returns hello2