在我正在合作的一个项目中,我们有两个选择可以使用哪个模块系统:
使用require导入模块,使用using module导出模块。Exports和Exports .foo。 使用ES6 import导入模块,使用ES6 export导出模块
使用其中一种是否有性能上的好处?如果我们要使用ES6模块而不是Node模块,还有什么我们应该知道的吗?
在我正在合作的一个项目中,我们有两个选择可以使用哪个模块系统:
使用require导入模块,使用using module导出模块。Exports和Exports .foo。 使用ES6 import导入模块,使用ES6 export导出模块
使用其中一种是否有性能上的好处?如果我们要使用ES6模块而不是Node模块,还有什么我们应该知道的吗?
当前回答
我个人使用import,因为我们可以通过import导入所需的方法和成员。
import {foo, bar} from "dep";
文件名:dep.js
export foo function(){};
export const bar = 22
这要归功于单霁翔。更多信息。
其他回答
最重要的是要知道ES6模块确实是一个官方标准,而CommonJS (Node.js)模块不是。
2019年,84%的浏览器支持ES6模块。虽然node .js将它们放在——experimental-modules标志后面,但还有一个称为esm的方便的节点包,这使得集成更加顺利。
在这些模块系统之间可能遇到的另一个问题是代码位置。Node.js假定source保存在node_modules目录中,而大多数ES6模块部署在平面目录结构中。解决这些问题并不容易,但可以通过破解你的软件包来实现。带有前后安装脚本的Json文件。这里有一个同构模块的例子和一篇解释它如何工作的文章。
使用ES6模块可以用于“摇树”;例如,启用Webpack 2、Rollup(或其他捆绑程序)来识别未使用/导入的代码路径,因此不会将其放入最终的捆绑程序中。这可以通过消除你永远不需要的代码来显著减少它的文件大小,但是默认情况下与CommonJS绑定,因为Webpack等人无法知道是否需要它。
这是使用代码路径的静态分析来完成的。
例如,使用:
import { somePart } 'of/a/package';
... 给捆扎者一个包装的暗示。anotherPart不是必需的(如果它没有被导入,它就不能被使用——对吧?),所以它不会费心捆绑它。
为了在Webpack 2中启用这个功能,你需要确保你的编译器不会吐出CommonJS模块。如果你正在使用带有babel的es2015插件,你可以像这样在.babelrc中禁用它:
{
"presets": [
["es2015", { modules: false }],
]
}
Rollup和其他工具的工作方式可能不同——如果您感兴趣,请查看文档。
到目前为止,ES6的导入和导出总是编译为CommonJS,所以使用其中一个没有好处。尽管推荐使用ES6,因为当浏览器发布本机支持时,它应该是有利的。原因是,你可以从一个文件中导入部分,而使用CommonJS,你必须需要整个文件。
ES6→导入,导出默认,导出
CommonJS→require, module。出口,exports.foo
下面是它们的常用用法。
ES6导出默认值
// hello.js
function hello() {
return 'hello'
}
export default hello
// app.js
import hello from './hello'
hello() // returns hello
ES6导出多个和导入多个
// 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
CommonJS module.exports
// hello.js
function hello() {
return 'hello'
}
module.exports = hello
// app.js
const hello = require('./hello')
hello() // returns hello
CommonJS模块。出口多
// 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
使用其中一种是否有性能上的好处?
目前的答案是否定的,因为目前没有一个浏览器引擎实现从ES6标准的导入/导出。
一些比较图表http://kangax.github.io/compat-table/es6/没有考虑到这一点,所以当你看到几乎所有的绿色Chrome,只是小心。没有考虑ES6中的import关键字。
换句话说,包括V8在内的当前浏览器引擎不能通过任何JavaScript指令从主JavaScript文件中导入新的JavaScript文件。
(在V8根据ES6规范实现之前,我们可能还会有几个bug或几年的时间。)
这个文件是我们需要的,这个文件是我们必须遵守的。
ES6标准说,模块依赖关系应该在我们读取模块之前就存在,就像在编程语言C中,我们有(headers) .h文件一样。
这是一个经过良好测试的结构,我相信创建ES6标准的专家们已经考虑到了这一点。
这使得Webpack或其他包捆绑器能够在某些特殊情况下优化包,并减少一些不需要的依赖包。但在完全依赖的情况下这永远不会发生。
导入/导出本地支持将需要一段时间,并且require关键字在很长一段时间内不会去任何地方。
需要什么?
这是node.js加载模块的方式。(https://github.com/nodejs/node)
Node使用系统级方法读取文件。在使用require时,你基本上依赖于它。require将在一些系统调用中结束,如uv_fs_open(取决于结束系统,Linux, Mac, Windows),以加载JavaScript文件/模块。
要检查这是否正确,请尝试使用Babel.js,您将看到import关键字将被转换为require。
我个人使用import,因为我们可以通过import导入所需的方法和成员。
import {foo, bar} from "dep";
文件名:dep.js
export foo function(){};
export const bar = 22
这要归功于单霁翔。更多信息。