今天学了一下JS的模块化编程,感觉JavaScript真的是博大精深,CommonJS,requireJS,NodeJS,Seajs,在此记录一下经验。JavaScript设计之初并不是一种模块化编程语言,不支‘类’和‘模块’的概念,但ES6中却将正式支持"类"和"模块"。有了模块,我们可以更方便地使用别人的代码,想要什么功能,就加载什么模块。 不过这样做的前提是大家必须以同样的方式编写模块,考虑到Javascript模块现在还没有官方规范,因此各种规范应运而生。
我们先来看看什么是模块化?
模块化是一种将系统分离成独立功能部分的方法,可严格定义模块接口、模块间具有透明性。模块化思想在后台语言中应用比较常见。
模块化有什么优缺点呢?
优点:
(1)可维护性 可以灵活架构,实现焦点分离,方便单个模块功能调试、升级,方便模块间组合、分解,多人协作互不干扰 。
(2)可分单元测试 。
缺点:
(1)对dom操作支持较弱,当然也可以使用jq;
(2)Html中过多指令、事件绑定的操作,耦合度较高
下面介绍两个概念:
内聚度 指模块内部实现,它是信息隐藏和局部化概念的自然扩展,它标志着一个模块内部各成分彼此结合的紧密程度。
好处也很明显,当把相关的任务分组后去阅读就容易多了。
设计时应该尽可能的提高模块内聚度,从而获得较高的模块独立性。
耦合度 则是指模块之间的关联程度的度量。耦合度取决于模块之间接口的复杂性,进入或调用模块的位置等。
与内聚度相反,在设计时应尽量追求松散耦合的系统。
目前,通行的Javascript模块规范共有两种:CommonJS和AMD+CMD。
CommonJS
2009年,美国程序员Ryan Dahl创造了node.js项目,将javascript语言用于服务器端编程。 这标志"Javascript模块化编程"正式诞生。
因为在浏览器环境下,有没有模块并不会造成多大影响;但是在服务器端,一定要有模块,与操作系统和其他应用程序互动,否则根本没法编程。
node.js的模块系统,就是参照CommonJS规范实现的。现在比较火的 React 及周边类库,就是直接使用 CommonJS 的模块体系,使用 npm 管理模块,使用 Browserify 打包输出模块。
在CommonJS中,有一个全局性方法require(),用于加载模块。
比如:要加载一个“math”模块,并使用里面的方法:
var math = require('math');
math.add(2,3); // 5
CommonJS规范有一个很大的局限性,由于他是同步加载,受网速快慢的影响非常大,如果长时间不能从服务器获得相应的资源,页面就会一直阻塞,不能正常加载。由于CommonJS规范的局限性,使得它并不适用于浏览器环境myapp,所以这个时候就出现了AMD和CMD;
CMD是国内玉伯大神在开发SeaJS的时候提出来的,属于CommonJS的一种规范,此外还有AMD,是RequireJS在推广的时候提出的一种规范,也使用require()来加载模块。二者都是异步模块定义(Asynchronuous Module Definition)的一个实现,不会影响其后的语句执行;
CMD和AMD的区别:
CMD相当于按需加载,定义一个模块的时候不需要立即制定依赖模块,在需要的时候require就可以了,比较方便;
AMD则相反,定义模块的时候需要制定依赖模块,并以形参的方式引入factory中。
CMD 推崇依赖就近,AMD 推崇依赖前置。
推荐阅读 阮一峰老师的文章 感觉讲的十分详尽。