远古时期
Js只是一门做简单交互功能的脚本语言,此时脚本语言的执行速度很慢,远远不如后端语言。
Ajax技术出现
在Ajax技术出现之前,浏览器端还不能用现在自定义接口的形式异步获取网页数据并局部刷新,只能通过浏览器的url
、script
标签、img
标签等进行网络请求获取服务器资源(全局刷新),若数据量大,用户会等待很长时间。Ajax出现后,网页可以动态获取数据局部渲染,js可以在页面上做复杂的交互功能了。大力推进了前端js的发展,并陆续出现很多js库
谷歌v8引擎出现
它解析js速度非常快,实现了js执行速度堪比后端服务器。同时在计算机领域,摩尔定律的出现也加速了计算机发展
刀耕火种的时代--原生JS组织阶段
在最原始的时代,我们是通过下面这种方式组织我们的模块代码的,将不同的JS文件在html中一一引入。每个文件代表一个模块:
// index.html
<script src="./a.js"></script>
<script src="./b.js"></script>
<script src="./c.js"></script>
<script src="./d.js"></script>
将每个模块包裹在一个函数作用域里面执行,这样就可以最大程度地避免污染执行环境。通过执行匿名函数得到模块输出,可以暴露给下面的其他模块使用:
<script>
var module1 = (function(){
var x = 1
return { a: x };
})();
</script>
<script>
var module2 = (function(){
var a = module1.a;
return { b: a };
})();
</script>
原始阶段的问题:
- 依赖混乱:
script
标签的先后顺序并不能很好地契合模块间的依赖关系。模块的依赖关系通常树状或网状的,相对复杂的依赖关系难以用script
标签的先后顺序组织 - 声明全局变量带来的环境污染和变量冲突
- 代码的逻辑关系难以理解,也不便于维护,容易出现某个脚本加载时依赖的变量尚未加载而导致的错误
- 对
script
标签顺序的要求而使用同步加载,但这却容易导致加载时页面卡死的问题
2009年commonJS诞生
工程师Kevin Dangoor创建了ServerJS小组,意在构建更好的Javascript生态系统,包括服务器端、浏览器端,而后更名为CommonJS小组。它指定了commonJS规范,后来被nodeJS所采用。由于commonJS的模块加载是同步的,服务器端加载的模块可以从内存或磁盘中加载,耗时基本可忽略,但浏览器端却会造成阻塞,白屏时间过长。因此,从commonJS中逐渐产生了其他分支规范,也就是后来的AMD、CMD。此时的commonJS规范只用来作为nodejs后端开发的模块化标准
2009年node诞生
一位名叫莱恩的精神小伙想设计一门服务端语言,能处理大吞吐量的场景。要大吞吐量,最好是单线程的,灵光一闪,js挺合适。于是设计了nodejs,并用谷歌v8引擎作为解释器。至此,js语言除了前端开发,也可以进行后端开发
2010年npm诞生
一年后,莱恩团队又发布了node自带的模块管理工具npm,npm全称是 node package manager,也就是node包管理器。npm从根本上改变了前端使用外部模块的方式,如果要打个比方的话,就好比从原始社会进入了现代社会。在一开始没有npm的时候,如果我们需要在项目里使用某个外部模块,我们可能会去官网直接把文件下载下来放到项目中,同时在入口html中通过script标签引用它
前端开发者们真正有了一个属于自己的社区和平台,如万千漂泊船归于港湾。npm的出现实际上是一个必然,前端工程的复杂化要求我们必须要有这么一个几何的js库管理平台。但为什么是npm呢?这和nodejs的火热有很大关系,因为npm是nodejs内置的包管理器,所以得到了开发者的追捧
2010年requireJS诞生
它遵循AMD规范,实现了前端模块化
2011年seaJS诞生
它遵循CMD规范,也实现了前端模块化
2012年webpack诞生
它最初是为了解决前端开发中的模块化问题而创建的,以前要想进行模块化开发,就必须借助于其他的工具,并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。而webpack可以让我们进行模块化开发,并会帮助我们处理模块间的依赖关系。而且不仅仅是js文件,css、图片、json文件等在webpack中都可以被当做模块来使用。在webpack出现之前,前端开发中经常使用手动引入脚本的方式来管理模块依赖关系,而随着项目复杂度的增加,这种方式变得越来越难以维护。webpack的出现使得开发者可以使用类似于nodejs的require语法来管理前端模块的依赖关系,用这样预处理的方式,把组织模块的工作提前做好,在代码部署上线前就完成,从而节约页面加载时间。且使用工具进行代码合并,把多个script的代码合并到少数几个script里,减少http请求的数量
2014年babel诞生
它让我们能够使用符合开发需求的编码风格去编写代码,然后通过babel的编译转化为对浏览器兼容良好的js。它让我们意识到:对前端项目来说,开发的代码和生产的前端代码可以是不一样的,也应该是不一样的。在babel出现之前的AMD/CMD时代,开发和生产的代码并没有明显的区分性
2015年ES Module模块化规范诞生
至此,模块化问题基本得到解决,js成为了可以编写大型应用的正式语言,有了和其他语言较量的资本
未来
Js既然可以放到服务器环境、浏览器环境,想当然也可以放到其他终端,于是用js开发桌面应用程序的Electron出现、用js可以开发移动端应用程序、小程序等
将来,所有的面向用户的跟人打交道、跟客户打交道的设备,都可用前端语言来实现,走向大前端生态。
ps✋✋✋: 目前,谷歌v8引擎已经全面支持ES Module模块化标准,但是node对ES Module的支持还在试验阶段,这里有很多历史包袱原因存在,如果node改成了ES Module模块化标准,以前的很多依赖它的第三方库就也要跟着变,那么势必会有很多第三方库就不能使用了。所以现在,node中还是以commonJS模块化为主!