基于CommonJS谈谈前端模块化

模块化

CMJ 被熟知得益于 Node 社区的炸裂兴起,不过目前 Node 已经转移向了 ESM。不过有兴趣的依然可以研究研究,Node 中的 CMJ 实现 NodeCMJ 实现源代码

1、模块化如何划分?

不管是 CMJ 还是 ESM,都不约而同的选择了以「文件」为基本单位来划分模块。

文件是组织代码结构的基本单位,在模块加载器自身的处理上来说,也是一个相对来说更容易的粒度~

2、如何使用?

// a.js
exports.action = function () {
  console.log('Action!');
}

// b.js
const a = require('./a.js');

a.action();

其实模块机制也是在设计 API,在设计层面,要注重考虑简洁、易用,CMJ 统一使用 require 关键字来引入模块,暴露模块的方式是挂载到 exports 对象引用上(当然也可以重写这个对象引用),这样的设计使得用户使用、学习起来没有过多的心智负担,想想一个模块加载器暴露给你的基本 API 就有十几个,你会觉得好用吗?

3、同步还是异步?

这也是设计之初就需要考虑到的问题,对模块的加载解析过程如果是异步,那必然和同步的处理方式有极大的区别,CMJ 是 之所以被 Node 采用,也是因为其设计之初考虑的就不是浏览器层面的,更偏向 Server, Node 本身在 IO 上就有足够的底气和实力,同步的方式契合了需求,只是目前推崇的 ESM 是官方的,未来的,Node 必须妥协于大流。

CommonJS不适用于浏览器端,因为它是同步的,对于浏览器不友好。

ESM

CMJ 的对比:

1、使用方式不同

CMJ: require and module.exports

ESM: import and export | export default

2、对基本类型,CMJ 是值拷贝,ESM 则是引用

3、动态运行时,静态编译(import 语句时静态执行,export 则是动态绑定的)

4、ESM 提升特性,import 必须写在文件最上方,不可用变量拼接路径

5、ESM 支持 Top-level awaitthis-undefined

6、ESM 天然支持 dynamic importCMJ 本身则是基于运行时

7、ESM 现在被大多数现代浏览器原生支持,通过 type="module" 进行标识 (相比较于CMJ,减少了build文件的过程)

8、同步,异步

ESM 将流程拆分为了三个步骤进行,首先是【构建阶段】解析模块,创建底层数据结构 Module Record(可以看成是 AST 结构节点),然后【实例化阶段】解析 import, export 存入内存(这个时候代码并没执行),【执行阶段】最后才是执行
然后将执行得到的结果放进对应的内存中,这样的过程拆分为了三个主要步骤,意味着 ESM 拥有了 CMJ 不具备的异步的能力!

为啥要拆成这么几个步骤?
前端常常面临的场景是多 chunk 渲染,通过入口文件 <script src='index.js' type='module'/>进来,可能需要加载很多 js 模块,这个时候如果 ESM 机制本身是多过程且可分离的,
就可以最大限度的压榨浏览器并行下载能力,快速加载依赖(当然底层支持按需更yyds),这是ES modules规范将算法分为多个阶段的原因之一

多阶段算法也有弊端,比如不能 import { foo } from "${fooPath}/a.js" 这样使用,因为构建依赖图是在第一阶段,这个时候路径信息是没有的
为了解决这个问题提出了 dynamic import,底层其实单独给这种情况创建了 Module Record,然后通过 module map 的方式管理起来(module map 就是一种管理 Module Record 的数据结构)

JS 引擎会深度优先后序遍历模块树,完成实例化过程,采用动态绑定的方式来联系 export import 值,这是和 CMJ 非常不同的地方

三阶段设计,天生支持循环引用
没有完成三阶段的时候,会标记为 Fetching 状态,循环引用的时候,看到是 Fetching 状态就先不管这里了,继续执行,等完成执行阶段,就会把对应的importexport链接到一个内存地址
这样就可以访问到了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值