在我正在合作的一个项目中,我们有两个选择可以使用哪个模块系统:
使用require导入模块,使用using module导出模块。Exports和Exports .foo。 使用ES6 import导入模块,使用ES6 export导出模块
使用其中一种是否有性能上的好处?如果我们要使用ES6模块而不是Node模块,还有什么我们应该知道的吗?
在我正在合作的一个项目中,我们有两个选择可以使用哪个模块系统:
使用require导入模块,使用using module导出模块。Exports和Exports .foo。 使用ES6 import导入模块,使用ES6 export导出模块
使用其中一种是否有性能上的好处?如果我们要使用ES6模块而不是Node模块,还有什么我们应该知道的吗?
当前回答
最重要的是要知道ES6模块确实是一个官方标准,而CommonJS (Node.js)模块不是。
2019年,84%的浏览器支持ES6模块。虽然node .js将它们放在——experimental-modules标志后面,但还有一个称为esm的方便的节点包,这使得集成更加顺利。
在这些模块系统之间可能遇到的另一个问题是代码位置。Node.js假定source保存在node_modules目录中,而大多数ES6模块部署在平面目录结构中。解决这些问题并不容易,但可以通过破解你的软件包来实现。带有前后安装脚本的Json文件。这里有一个同构模块的例子和一篇解释它如何工作的文章。
其他回答
主要优势是句法上的:
更多的声明性/紧凑语法 ES6模块基本上会让UMD(通用模块定义)过时——基本上消除了CommonJS和AMD(服务器vs浏览器)之间的分裂。
使用ES6模块你不太可能看到任何性能上的好处。你仍然需要一个额外的库来捆绑模块,即使在浏览器中完全支持ES6特性。
当涉及到异步或延迟加载时,import()要强大得多。当我们以异步方式需要该组件时,我们会以某种异步方式使用import,例如在const变量中使用await。
const module = await import('./module.js');
或者如果你想使用require(),
const converter = require('./converter');
import()实际上在本质上是异步的。正如neehar venugopal在ReactConf中提到的,你可以使用它来动态加载客户端架构的react组件。
此外,当涉及到路由时,它是更好的方式。这是使网络日志在用户连接到特定网站时下载到其特定组件的一个特殊之处。例如,在仪表板之前的登录页面不会下载仪表板的所有组件。因为什么是需要当前即登录组件,这只会下载。
导出也一样:ES6的导出与CommonJS module.exports完全相同。
注:如果你正在开发一个node.js项目,那么你必须严格使用require(),因为如果你将使用import,节点将抛出异常错误作为无效的令牌'import'。所以node不支持import语句。
更新-根据Dan Dascalescu的建议:自v8.5.0(2017年9月发布)以来,node -experimental-modules索引。mjs让你不用Babel就可以使用import。你也可以(也应该)将你的npm包作为原生ESModule发布,并向后兼容旧的require方式。
在哪里使用异步导入,请参见https://www.youtube.com/watch?v=bb6RCrDaxhw
ES模块是静态的,这意味着导入是在每个模块的顶层描述的,并且在任何控制流语句之外。这是行不通的: If(条件){ 从'module1'导入module1 }
但是在commonjs中,它是允许的:
if (condition) {
module = require('module1')
}
ES modules run implicitly in strict mode. This means that we don't have to explicitly add the "use strict" statements at the beginning of every file. Strict mode cannot be disabled; therefore, we cannot use undeclared variables or the with statement or have other features that are only available in non-strict mode. strict mode is a safer execution mode. In ESM, some important CommonJS references are not defined. These include require , exports , module.exports , __filename, and __dirname. We can import CommonJS modules from ESM by using the standard import syntax. But only default exports work: import packageName from 'commonjs-package' // Works import { moduleName } from 'commonjs-package' // Errors
但是,从CommonJS模块中导入ES模块是不可能的。
ESM不能直接将JSON文件作为模块导入,这个特性在CommonJS中使用非常频繁。这就是为什么在reactjs中使用fetch api。 从'./data导入数据。json / /失败
最重要的是要知道ES6模块确实是一个官方标准,而CommonJS (Node.js)模块不是。
2019年,84%的浏览器支持ES6模块。虽然node .js将它们放在——experimental-modules标志后面,但还有一个称为esm的方便的节点包,这使得集成更加顺利。
在这些模块系统之间可能遇到的另一个问题是代码位置。Node.js假定source保存在node_modules目录中,而大多数ES6模块部署在平面目录结构中。解决这些问题并不容易,但可以通过破解你的软件包来实现。带有前后安装脚本的Json文件。这里有一个同构模块的例子和一篇解释它如何工作的文章。
到目前为止,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