commonJs
commonJs的全称是Common Module Definition,可以理解为一种模块加载规范。
javascript是一种脚本语言,可能大家早已经习惯了require,import之类的模块加载方式。这一系列的便利都是建立在相应的规范之上的。commonJS就是规范的一种,该规范主要规定了如何去定义一个包,以及如何去引入一个包。大家只需要按照这个规范执行即可,但是这只是一个规范,具体怎么去实现就见仁见智了。
一般浏览器里运行js直接通过script src=”some_script.js”>就可以引入脚本执行了,而且一般不会太复杂,有没有模块化无关紧要(相对而言)。但是对于服务器端,只有解决了模块化才有可能采用JavaScript进行相应开发。
nodejs正是一个commonJs规范的实现,在node里正是采用require的方式进行包的引入。至于定义以及原理,这里不继续说明了。只需要满足commonJs规范,就能使用通用的方式进行包的引入。这里主要涉及到的几个变量是module,export,global,require,简单理解就是,将变量绑定到module.exports上,就能实现不同文件之间的引用。
AMD
有了commonJs看似很美好,解决了javaScript包的问题。但是commonJs的加载规则是同步加载,这也就意味着,如果在页面上有很多包加载,则必须等待所有包加载完毕以后才能开始渲染页面,此时会导致页面卡死的现象。为了解决这个问题,人们提出了Asynchronous Module Definition,这个规范则是规定了异步加载的包引入和定义方法。与commonJS类似,只要按照这个规定进行实现即可采用统一的方法进行包的引入。而require.js是最出名的一个实现。AMD会异步地加载依赖包,保证页面的正常渲染。AMD有一个很大的问题是必须按照它的规定来编写包文件,这就导致了很多第三方包的不兼容。为了解决这个问题,出现了commonJs wrapping写法,这一写法能够兼容commonJs的包,但是也会带来一些负面问题。只需要按照相应的教程,完全可以引入commonJs规范的包。
CMD
貌似有了commonJs和AMD,已经完全解决了前后端的包的问题,但是在一些场景下AMD的表现并不是最佳的,所以就衍生出了CMD。虽然AMD是异步加载依赖包的,但是CMD会在一开始就把所有的依赖包加载进来,然后在执行后续的代码。如果依赖包过大,则刚开始的时候页面就可能出现卡死现象。为了改善这一现象,CMD出现了。CMD对包的加载过程是按需加载,会在用到相应的包的时候进行加载,这样就保证了页面能够更快地进入可用状态。但是这样也会带来一些负面作用,比如使用过程中出错回滚,包之间的依赖处理等问题。CMD的一个著名的实现就是sea.js。
总之,commonJS是主要针对后端的包加载规范,AMD和CMD都是针对前段的包加载规范。各种规范有不同的适用场景,都有很成熟的实现了,只需要按照需要使用即可。
下面是几个精辟的文章,可以展开阅读。