基于CommonJS谈谈前端模块化
模块化
CMJ
被熟知得益于 Node
社区的炸裂兴起,不过目前 Node
已经转移向了 ESM
。不过有兴趣的依然可以研究研究,Node
中的 CMJ
实现 Node
中 CMJ
实现源代码
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 await
,this-undefined
6、ESM
天然支持 dynamic import
,CMJ
本身则是基于运行时
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
状态就先不管这里了,继续执行,等完成执行阶段,就会把对应的import
和export
链接到一个内存地址
这样就可以访问到了
基于CommonJS谈谈前端模块化相关推荐
- 前端模块化——彻底搞懂AMD、CMD、ESM和CommonJS
我们知道,在NodeJS之前,由于没有过于复杂的开发场景,前端是不存在模块化的,后端才有模块化.NodeJS诞生之后,它使用CommonJS的模块化规范.从此,js模块化开始快速发展. 模块化的开发方 ...
- 前端模块化CommonJS、AMD、CMD、ES6
一.前端模块化 什么是模块化?为什么前端需要模块化? js代码量激增,放在同一个文件里面,不容易维护,而且牵一发而动全身. 这时候就需要将代码按照逻辑放在不同的文件里面,按照一定的语法规则,遵循特定的 ...
- fis pure开发php,GitHub - fex-team/fis-pure: 基于FIS的纯前端模块化解决方案
fis-pure 基于FIS的纯前端模块化解决方案pure. 建议刚接触这个方案的同学直接使用 FIS3 而非 pure,FIS3可以更轻松的实现 pure 的功能. pure是基于FIS二次封装能力 ...
- 前端模块化详解(CommonJS、AMD、CMD、ES Module)
大家好,我是一碗周,一个不想被喝(内卷)的前端.如果写的文章有幸可以得到你的青睐,万分有幸~ 写在前面 随着前端项目的不断复杂,代码日益膨胀,项目的维护难度随之越来越大,此时模块化也就相继的出现了,本 ...
- 前端模块化 CommonJs、AMD、CMD、UMD、ESmodule 发展历程与关系
前端模块化 发展过程 NodeJS之前,前端不存在模块化,后端有模块化. NodeJS诞生之后,它开始使用CommonJS模块化规范. 特点 一个文件就是一个模块,有自己的作用域,只向外暴漏特定的变量 ...
- 前端模块化开发学习之gulpbrowserify篇
随着web应用的发展,前端的比重占得越来越多,编写代码从而也越来越复杂.而通常我们需要将不同功能或者不同模块的代码分开写,最后在html中一起加载,这样做是可以的,但是当你需要进行维护或者是二次开发 ...
- 模块化加载_前端模块化简单总结
来源 | http://www.fly63.com/article/detial/9827 前言 JavaScript初期就是为了实现简单的页面交互逻辑,如今CPU.浏览器性能得到了极大的提升,很多页 ...
- 基于webpack搭建前端工程解决方案探索
关于前端工程 \\ 下面是百科关于"软件工程"的名词解释: \\ \ 软件工程是一门研究用工程化方法构建和维护有效的.实用的和高质量的软件的学科. \ \\ 其中,工程化是方法,是 ...
- 最全面、最详细的“前端模块化”总结
背景 随着前端功能越来越复杂,前端代码日益膨胀,为了减少维护成本,提高代码的可复用性,前端模块化势在必行. 所有js文件都在一个html中引入,造成以下不良影响: 请求过多.首先我们要依赖多个模块,那 ...
最新文章
- 解决 Xcode10 编译错误 ld: library not found for -lstdc++6.0.9
- linux下延时1ms用什么函数,Linux下1ms分辨率定时器推荐方式
- 2021年高考理综单科成绩查询,2021年高考总分是多少 2021年高考各科满分多少分...
- python123第七周小测验_python+request+untitest的接口自动化测试
- [Ext JS 4] 实战之Load Mask - 在Grid Reconfigure的使用状况
- 荣获2009年“微软最有影响力开发者”称号
- SET NOCOUNT
- c#中两种不同的存储过程调用与比较
- java 读mdb,使用Java / Jackcess从加密的Access .mdb中读取
- 虚拟打印机可以设置默认保存路径吗
- 颜色码和抽出滤镜二步抠出飘发美女
- BankNext 微服务:案例研究
- 瀑布流插件WookMark
- Retouch4me 套件 -- 人像自动精修插件
- vue解析excel文件(使用xlsx)
- JS每晚24:00更新某方法
- 浏览器插件实现GitHub代码翻译原型演示
- windows下,基于python3的wxpython体验+cxfreeze6.0使用
- python web开发--web前端开发介绍
- AI人工智能 容智RPA银行机器人的优势