esmodule 和 commonjs到底有什么区别

我要说的,就算不知道两者之间的区别,你在写node和浏览器里面的编程时,也不会导致多大的问题,网络上吹毛求疵的说法太过夸张了。

在网上搜了一圈,很多文章抄袭于阮老师的总结:https://es6.ruanyifeng.com/#docs/module-loader, 没有提出自己的见解。

阮老师的科普文章写的很好,这篇基本也提炼出表象,但是对于总结出的三点区别,我个人理解起来还是容易混淆不够透彻,所以我基于这部分又作了深入的挖掘,花了点时间读取规范才终于彻底搞明白了:
https://tc39.es/ecma262/#sec-ecmascript-language-scripts-and-modules

最根本的区别

来自于两点:

一是esm是为浏览器的加载环境设计的,考虑到网络的延迟,不可以等到模块彻底解析完成(同步)再去加载索引加载其他的模块,所以会以最快的速度建立出树形的map,再去解析装载具体的内容,这用异步去解释也能解释的通,但是它实际的过程就是这个过程,跟异步什么的关联不大。

二是esmimport的实际就是export出的值,它们使用的是同一个空间(内存)。而common js require的是module.exports的值, 返回的实际就是这个module.exports,只是因为获取的语法是var xx = require('...'),这只是导出的方式有细微的区别。本质是可以理解的。这是语法上的差异。

下图可以说明这种语法的本质:

所以可以说,commonsjsrequire("...")返回的也是值的本身,只不过我们使用一个变量声明赋值的语法来获取这个值而已。

所以当你直接修改require返回的值,也可以起到一样的效果:

//counter.js
var num = 0;

function increment() {
  num += 1;
}

module.exports = {
  num,
  increment
}

// index.js
require('./counter').num +=2
var counter = require('./counter');

console.log(counter.num);

输出:

2
posted @ 2021-02-02 12:12  ViCanary  阅读(778)  评论(0编辑  收藏  举报