3分钟让你理解CommonJS和ES6模块化的区别

原创
小哥 3年前 (2022-10-21) 阅读数 131 #Web前端
文章标签 ES6CommonJS

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模块
版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除