因为这个问题,我产生了写一个系列文章的想法,试图从站在历史的角度上来看待编程世界中林林总总的问题和解决方案。
目前中文网络上充斥着大量互相“转载”的内容,基本是某一个技术问题的解决方案(what? how?),却不涉及为什么这么做和历史缘由(why? when?)。比如你要搜 “JavaScript 有哪些模块化方案?它们有什么区别?”,能得到一万个有用的结果;但要想知道 “为什么 JavaScript 有这么多模块化方案?它们是谁创建的?”,却几乎不可能。
因此,这一系列文章内会尽可能的不涉及具体代码,只谈历史故事。但会在文末提供包含部分代码的参考链接,以供感兴趣的朋友自行阅读。
这个系列暂定为十篇文章,内容会涉及前端、后端、编程语言、开发工具、操作系统等等。也给自己立个 Flag,在今年年底之前把整个系列写完。如果没完成目标……就当我没说过这句话(逃
全系列索引:
《编程时间简史系列》JavaScript 模块化的历史进程
《编程时间简史系列》Web Server 编年史
正文
模块化,是前端绕不过去的话题。
随着 Node.js 和三大框架的流行,越来越多的前端开发者们脑海中都会时常浮现一个问题:
为什么 JavaScript 有这么多模块化方案?
自从 1995 年 5 月,Brendan Eich 写下了第一行 JavaScript 代码起,JavaScript 已经诞生了 25 年。
但这门语言早期仅仅作为轻量级的脚本语言,用于在 Web 上与用户进行少量的交互,并没有依赖管理的概念。
随着 AJAX 技术得以广泛使用,Web 2.0 时代迅猛发展,浏览器承载了愈来愈多的内容与逻辑,JavaScript 代码越来越复杂,全局变量冲突、依赖管理混乱等问题始终萦绕在前端开发者们的心头。此时,JavaScript 亟需一种在其他语言中早已得到良好应用的功能 —— 模块化。
其实,JavaScript 本身的标准化版本 ECMAScript 6.0 (ES6/ES2015) 中,已经提供了模块化方案,即 ES Module。但目前在 Node.js 体系下,最常见的方案其实是 CommonJS。再加上大家耳熟能详的 AMD、CMD、UMD,模块化的事实标准如此之多。
那么为什么有如此之多的模块化方案?它们又是在怎样的背景下诞生的?为什么没有一个方案 “千秋万代,一统江湖”?
接下来,我会按照时间顺序讲述模块化的发展历程,顺带也就回答了上述几个问题。
萌芽初现:从 YUI Library 和 jQuery 说起
时间回到 2006 年 1 月,当时还是国际互联网巨头的 Yahoo(雅虎),开源了其内部使用已久的组件库 YUI Library。
YUI Library 采用了类似于 Java 命名空间的方式,来隔离各个模块之间的变量,避免全局变量造成的冲突。其写法类似于:
YUI.util.module.doSomthing();
这种写法无论是封装还是调用时都十分繁琐,而且当时的 IDE 对于 JavaScript 来说智能感知非常弱,开发者很难知道他需要的某个方法存在于哪个命名空间下,经常需要频繁地查阅开发手册,导致开发体验十分不友好。
在 YUI 发布之后不久,John Resig 发布了 jQuery。当时年仅 23 岁的他,不会知道自己这一时兴起在 BarCamp 会议上写下的代码,将占据未来十几年的 Web 领域。
jQuery 使用了一种新的组织方式,它利用了 JavaScript 的 IIFE(立即执行函数表达式)和闭包的特性,将所依赖的外部变量传给一个包装了自身代码的匿名函数,在函数内部就可以使用这些依赖,最后在函数的结尾把自身暴露给 window。这种写法被很多后来的框架所模仿,其写法类似于:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。