0-模块化开发的历史

前端模块化
指的范围比较广具体有
‘html模块化’:jsp的include、php的include、前端的iframe等等,因为页面数据一般与程序的model绑定在一起的,所以html的模块化往往要结合异步js、或同步后端语言来完成。所以一般没有人去单独说html的模块化,当然如果html是纯静态资源就无所谓了
‘js模块化’:划重点
‘css模块化’:参考 https://www.jianshu.com/p/d46bc8cf3afa
html模板可复用、css可复用、js可复用
目前我觉得做的最好的就是基于脚手架搭建的vue项目了,因为一个单文件组件就是一个模块,而一个模块内包含了独立可服用的所有前端的东西--模板(html)、表现(css)、行为(js)



前端模块化与js模块化
因为js是最能体现出前端模块化,所以一般说前端模块化指的就是js模块化

讲讲js模块化开发历史
上边我也说了,前端模块开发的重点在于js模块化开发,所以我下边讲的都是js模块化开发
JavaScript作为一款灵活性和可塑性较强的语言,由前端到后端显示了它及其旺盛的生命力。而JavaScript的模块化之路却比较坎坷和多元化,初学者可能会对这些概念及其关系搞得晕头转向,比如CommonJS、AMD、ES6、CMD、UMD等。本文将简要概述它们之间的关系和区别,为了理清它们之间的关系,我画了张图。


CommonJS
CommonJS规范出现的最早,它的目的很明确,就是解决JavaScript的模块开发规范问题

我们先从CommonJS谈起,因为在网页端没有模块化编程只是页面JavaScript逻辑复杂,但也可以工作下去,在服务器端却一定要有模块,所以虽然JavaScript在web端发展这么多年,第一个流行的模块化规范却由服务器端的JavaScript应用带来,CommonJS规范是由NodeJS发扬光大,这标志着JavaScript模块化编程正式登上舞台。但是等到在浏览器实现的时候,尴尬的事情来了,NodeJS应用加载的模块都是基于本地磁盘的,而浏览器却收到网络延迟的影响,而各个模块的延迟长短并不确定,这就给依赖造成了很大的麻烦,比如执行模块先于被依赖的模块下载下来了,那么是执行失败。也就是说,CommonJS是适用于同步的,而客户端的js均是异步加载的,并不适应该规范,于是AMD就出现了。

AMD
AMD 即Asynchronous Module Definition,中文名是异步模块定义的意思。它是一个在浏览器端模块化开发的规范,由于不是JavaScript原生支持,使用AMD规范进行页面开发需要用到对应的库函数,也就是大名鼎鼎RequireJS,实际上AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出。
利用异步回调的思路,成功的解决了CommonJS问题‘多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器’。但是继而又引发了一个问题--js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长,AMD的模块依赖在声明的时候就要被全部加载到浏览器中执行一遍。即所谓的‘AMD是依赖前置,提前加载依赖’。CMD就诞生了

CMD
实际上AMD就已经是完美的前端模块式开发了,但是为了优化性能,还是出了CMD模块化开发规范。CMD性能好,因为只有用户需要的时候才执行。项目加载的时候,会把所有的所依赖的js下载到本地,但是并不执行,直到遇到require某模块的时候,才会被执行。即所谓的‘CMD依赖后置,使用时才加载’
这样项目所需依赖则js完全存储到本地了,然后就可以如同nodeJs(commonJs)一样去require了

AMD与CMD的最大区别
AMD会下载完所有的依赖并全部执行加载到浏览器,
而CMD只会把所有的依赖预先下载到本地,但是并不会立即执行一次(加载到浏览器)。
AMD下载>加载(也叫做执行、解释)
CMD下载>遇到require则加载

很多人说AMD用户体验好,因为没有延迟,依赖模块提前执行了,CMD性能好,因为只有用户需要的时候才执行。仁者见仁智者见智吧。

至于UMD我觉得纯属扯淡,本事知识点不多,就是加了判断当前是什么环境,用那种模块化开发机制好

作者感想

前后端模块化的最大差别在于
  模块文件读取 规范
后端 同步所有的文件均在服务器本地,所以加载起来时间完全可以忽略。也就是说java的import xxx,node的requre xxx,php的include不同文件时,谁在前,谁先被引入 拿java来说,模块化机制从诞生那一刻就有了,一个packge就是一个模块,是用import导入,即可访问里边所有的class等等不存在争议

node,一个文件就是一个模块,用require去导入,即commomJ规范,也没争议
前端

所有文件均在服务器,而js脚本确实在客户端执行,如果用同步的方式去引入,放在前边的,受网络影响,并不一定会先加载进来,如果程序需要按顺序加载执行某些逻辑,就不行了,这也是为啥AMD、CMD诞生的原因了

当然啊,如果是webapp、小程序啊,这些所有文件都是在本地的,是完全不受约束的

AMD、CMD
define来定义模块,CMD建议一个文件定义一个模块,即一个文件只有一个define

Es6的import目前只是语法糖,es的模块化规范尚未真正完善,而且浏览器目前也均无法实现

 



对规范支持

如果模块化开发的话,后端node平台是直接支持的,但是前端就不行了,浏览器这些规范、关键字均不被识别
所以要想使用这些模块化开发,有两种办法,要么使用他们的实现require.js、sea.js,或者使用webpack、babel编译成浏览器识别的
除此之外,像小程序是微信端直接支持模块开发的,提供了机制和关键字,其底层实质估计多半也是用了webpack进行编译的
像脚手架搭建的vue项目也是能直接使用模块化开发的,底层多半也是用了webpack编译,只是是自动化热编译,你察觉不带而已
还有angular(注意不是angularJs)也是同样的原因可以直接使用模块开发(angular这个套的有深一些,他是用了typescript语法import什么的,然后被webpack编译成es5被浏览器执行)

参考
http://www.qdfuns.com/notes/20963/fc5ee24d4c0cff32334846bdd0c74c42.html
http://www.zhaiqianfeng.com/2017/06/ES6-CommonJS-CMD-AMD-UMD.html
https://www.cnblogs.com/jackyWHJ/articles/4943271.html
https://www.cnblogs.com/highsea90/p/4383895.html
http://blog.csdn.net/csdn_yudong/article/details/52206789
http://www.ruanyifeng.com/blog/2012/10/javascript_module.html

原文地址:https://www.cnblogs.com/dshvv/p/8371018.html