3分钟让你理解CommonJS和ES6模块化的区别
原创1、使用环境
- CommonJS模块的require语法是同步的,结果是CommonJS模块规范 只适合在服务端使用 。因为如果在浏览器端同步加载一个模块,需要网络来确定速度,响应时间可能会很长。
- ES6模块要么在。 可以使用浏览器端或服务器端。 ,但在服务器端,您还需要遵循一些特殊的规则才能使用。
2,以不同的方式输出
- CommonJS输出是一个值 拷贝
- ES6该模块输出值 引用
CommonJS-值的拷贝
CommonJS输出是值的副本,换句话说,一旦输出了某个值,模块内部的后续更改就不能影响该值的外部使用。
// lib.js
var counter = 3;
function incCounter() {
counter++;
}
module.exports = {
counter: counter,
incCounter: incCounter,
};
然后,我们在其他文件中使用此模块:
var mod = require(./lib);
console.log(mod.counter); // 3
mod.incCounter();
console.log(mod.counter); // 3
上面的例子证明,如果我们出口 conter
变量,即使后续调用模块的内部 incCounter
方法来修改其值,则其值不会更改。
ES6模块-值的引用
ES6模块的运行机制完全不同,JS 当引擎静态分析脚本时,它会遇到模块加载命令。import,则会生成只读引用。当脚本实际执行时,将根据该只读引用从加载的模块中获取该值。
// lib.js
export let counter = 3;
export function incCounter() {
counter++;
}
// main.js
import { counter, incCounter } from ./lib;
console.log(counter); // 3
incCounter();
console.log(counter); // 4
以上都证明了,ES6模块 import
的变量 counter
是可变的,并在模块中完全反映它。 lib.js
内部变化
3、运行时加载和编译时加载。
- CommonJS模块是 运行时加载
- ES6模块是 编译时输出接口
CommonJS-运行时加载
// CommonJS模块
let { stat, exists, readfile } = require(fs);
// 等同于
let _fs = require(fs);
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;
上述代码的本质是整体加载fs模块(即,加载fs在所有方法中),生成一个对象(_fs),然后从该对象上方读取。 3 方法:研究方法。这种加载被称为运行时加载,因为只有运行时才能获得此对象,导致无法在编译时进行“静态优化”
ES6模块-编译时加载
import { stat, exists, readFile } from fs;
上述代码的精髓来自fs模块加载 3 方法,则不加载其他方法。这种加载称为“编译时加载”或静态加载,即E。 ES6 模块加载可以在编译时完成,这样效率更高 CommonJS 该模块的加载方式较高。当然,这也导致了没有参考。 ES6 模块本身,因为它不是对象。
小结
CommonJS事实上,它加载了一个对象,该对象仅在脚本运行时生成,并且只生成一次。但ES6一个模块不是一个对象,它的外部接口只是一个静态定义,它是在代码的静态解析阶段生成的,所以我们可以使用各种工具JS模块执行依赖项分析、优化代码和Webpack中的 tree shaking 和 scope hoisting 事实上,这是一种依赖ES6模块化。
4,相互参考
- ES6模块,是为了支持加载CommonJS模块的
- 但是,CommonJS并不支持requireES6模块
总结
- 因为CommonJS的require语法是同步的,结果是CommonJS仅适合在服务器端使用;以及ES6模块在浏览器端和服务器端都可用,但在服务器端需要遵循特殊规则。
- CommonJS模块输出是一个值拷贝,而ES6该模块输出值引用
- CommonJS模块在运行时加载;ES6该模块是编译时输出的接口,便于JS用于静态分析的模块
- 在相互参照的问题上,ES6该模块支持加载。CommonJS;而CommonJS不支持引用ES6模块
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除
上一篇:H5 中DOCTYPE的作用 下一篇:JS中怎么解析url中的参数