精读 js 模块化发展

这次是前端精读期刊与大家第一次正式碰面,我们每周会精读并分析若干篇精品好文,试图讨论出结论性观点 。没错,我们试图通过观点的碰撞,争做无主观精品好文的意见领袖 。
我是这一期的主持人 —— 黄子毅
本期精读的文章是:ity 。
懒得看文章?没关系,稍后会附上文章内容概述,同时,更希望能通过阅读这一期的精读,穿插着深入阅读原文 。
1 引言

精读 js 模块化发展

文章插图
如今,模块化规范非常方便、自然,但这个新规范仅执行了2年,就在 4 年前,js 的模块化还停留在运行时支持,10 年前,通过后端模版定义、注释定义模块依赖 。对经历过来的人来说,历史的模块化方式还停留在脑海中,反而新上手的同学会更快接受现代的模块化规范 。
但为什么要了解模块化发展的历史呢?因为凡事都有两面性,了解模块化规范,有利于我们思考出更好的模块化方案,纵观历史,从 1999 年开始,模块化方案最多维持两年,就出现了新的替代方案,比原有的模块化更清晰、强壮,我们不能被现代模块化方式限制住思维,因为现在的模块化方案距离发布也仅仅过了两年 。
2 内容概要
直接定义依赖 (1999): 由于当时 js 文件非常简单,模块化方式非常简单粗暴 —— 通过全局方法定义、引用模块 。这种定义方式与现在的非常神似,区别是以文件作为模块,而这种方法可以在任何文件中定义模块,模块不与文件关联 。
闭包模块化模式 (2003): 用闭包方式解决了变量污染问题,闭包内返回模块对象,只需对外暴露一个全局变量 。
模版依赖定义 (2006): 这时候开始流行后端模版语法,通过后端语法聚合 js 文件,从而实现依赖加载,说实话,现在 go 语言等模版语法也很流行这种方式,写后端代码的时候不觉得,回头看看,还是挂在可维护性上 。
注释依赖定义 (2006): 几乎和模版依赖定义同时出现,与 1999 年方案不同的,不仅仅是模块定义方式,而是终于以文件为单位定义模块了,通过加载文件,同时读取文件注释,继续递归加载剩下的文件 。
外部依赖定义 (2007): 这种定义方式在 -js 开发中普遍使用,其核心思想是将依赖抽出单独文件定义,这种方式不利于项目管理,毕竟依赖抽到代码之外,我是不是得两头找呢?所以才有通过打包为一个文件的方式暴力替换为的方式出现 。
模式 (2009): 这种模块化方式很简单,暴力,将所有模块塞到一个变量中,硬伤是无法解决明明冲突问题,毕竟都塞到一个对象里,而对象也需要定义在全局,存在被覆盖的风险 。模块化需要保证全局变量尽量干净,目前为止的模块化方案都没有很好的做到这一点 。
依赖注入 (2009): 就是大家熟知的 .0,依赖注入的思想现在已广泛运用在 react、vue 等流行框架中 。但依赖注入和解决模块化问题还差得远 。
(2009): 真正解决模块化问题,从 node 端逐渐发力到前端,前端需要使用构建工具模拟 。
Amd (2009): 都是同一时期的产物,这个方案主要解决前端动态加载依赖,相比,体积更小,按需加载 。
Umd (2011): 兼容了与 Amd,其核心思想是,如果在环境(存在 .,不存在 ),将函数执行结果交给 . 实现,否则用 Amd 环境的,实现 Amd 。
(2012): 和很像了,没什么硬伤,但生不逢时,碰上与 Amd,那只有被人遗忘的份了 。
(2013): 既然都出了Amd,文章还列出了此方案,一定有其独到之处 。其核心思想在于使用取代,可以控制模块结束时机,处理异步结果;拿到第二个参数,修改其他模块的定义(虽然很有拓展性,但用在项目里是个搅屎棍) 。