您的位置:首页 > 产品设计 > UI/UE

CommonJs, AMD/RequireJs,CMD/seajs, UMD, webpack

2017-12-20 16:52 399 查看


JavaSript模块化

在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?

模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题进行系统性的

分解以之处理。模块化是一种处理复杂系统分解为代码结构更合理,可维护性更高的可管理的模块的方

式。可以想象一个巨大的系统代码,被整合优化分割成逻辑性很强的模块时,对于软件是一种何等意义的

存在。对于软件行业来说:解耦软件系统的复杂性,使得不管多么大的系统,也可以将管理,开发,维护

变得“有理可循”。

还有一些对于模块化一些专业的定义为:模块化是软件系统的属性,这个系统被分解为一组高内聚,低

耦合的模块。那么在理想状态下我们只需要完成自己部分的核心业务逻辑代码,其他方面的依赖可以通过

直接加载被人已经写好模块进行使用即可。

首先,既然是模块化设计,那么作为一个模块化系统所必须的能力:
1. 定义封装的模块。
2. 定义新模块对其他模块的依赖。
3. 可对其他模块的引入支持。

好了,思想有了,那么总要有点什么来建立一个模块化的规范制度吧,不然各式各样的模块加载方式只

会将局搅得更为混乱。那么在JavaScript中出现了一些非传统模块开发方式的规范 CommonJS的模块规

范,AMD(Asynchronous Module Definition),CMD(Common Module Definition)等。
http://blog.chinaunix.net/uid-26672038-id-4112229.html




 Seasons123 changed
the title from mst-CMD,AMD,UMD,commonjs,requirejs,seajs to mst-关于模块化:CMD,AMD,UMD,commonjs,requirejs,seajs on
22 Jun




 Seasons123 changed
the title from mst-关于模块化:CMD,AMD,UMD,commonjs,requirejs,seajs tomst-关于模块化:CMD,AMD,UMD,commonjs,requirejs,seajs,webpack on
22 Jun

 
Owner


Seasons123 commented on
22 Jun • 

edited 


commonjs

commonjs起初是服务端模块的规范,nodejs就是采用这个规范。CommonJs原来是叫ServerJs,从名字可以看出是专攻服务端的,为了统一前后端而改名CommonJs。它的规范是一个单独的文件就是一个模块。加载模块使用require方法,该方法读取文件并执行,最后导出一个exports对象。commonjs是同步加载模块,加载完成后执行操作。服务端require一个模块,直接就从硬盘或者内存中读取了,消耗的时间可以忽略,就没有必要采用异步方式的来加载。但是如果我们考虑到浏览器端的话,就肯定知道,同步加载,阻塞页面的渲染,造成页面白屏,或者卡死等现象,对于用户体验肯定是不友好的。另外,资源的加载方式与服务端完全不同,在浏览器端,需要从服务端来下载这个文件,然后运行里面的代码才能得到API,需要花费一个http请求,也就是说,require后面的一行代码,需要资源请求完成才能执行。由于浏览器端是以插入<script>标签的形
11f9b
式来加载资源的(ajax方式不行,有跨域问题),没办法让代码同步执行,所以像commonjs那样的写法会直接报错。所以就有了AMD,CMD.


AMD

即Asynchronous Module Definition的缩写,字面意思”异步模块定义”,就是一种规范。依赖前置(依赖在使用之前都必须提前加载)。requirejs可以简单理解为AMD规范的一种实现。下面介绍。

AMD写模块的api如下:
define(id,dependencies,factory);


(1)id

string类型,一般表示模块名称,或者说标识,是一个可选参数。如果该参数不存在的话。如果没有提供

该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字。如果提供了该参数,模块名必是“顶级”的和绝对的(不允许相对名字)。

模块名的格式
模块名用唯一标识定义,它们同样在依赖数组中使用。AMD的模块命名规范是Commonjs模块命名规范的
超集。
模块名是由一个或多个单词以正斜杠为分隔符拼接成的字符串
单词须为驼峰形式,或者”.”,”..”
模块名不允许使用文件扩展名的形式,如”.js”
模块名可以为”相对的”或者”顶级的”。如果首字符为”.”或者”..”则为”相对的”模块名
顶级的模块名从根命名空间的概念模块解析
相对的模块名从”require”书写和调用的模块解析

(2) dependencies

数组类型。是定义中模块所依赖模块的一个数组。依赖模块必须根据模块的工厂方法优先级执行,并且执

行的结果应该按照数组中的位置顺序以参数的形式传入(定义中模块的)工厂方法中。依赖的模块名如果是

相对的,应该解析为相对定义中的模块。相对名解析为相对于模块的名字,并非相对于寻找该模块的名字

和路径。该参数也是可选参数,如果没有这个参数,它默认为[“require”, “exports”, “module”]。然而,如

果工厂方法的形参个数小于3,加载器会选择以函数指定的参数个数调用工厂方法

(3)factory

值的类型多选。是模块初始化要执行的函数或者对象。如果是函数的话,它应该只被执行一次。如果是对

象,此对象应该为模块的输出值。如果工厂方法返回一个值(对象,函数,或任意强制类型转换为true的

值),应该被设置为模块的输出值。以上引用https://github.com/amdjs/amdjs-api/wiki/AMD-

(%E4%B8%AD%E6%96%87%E7%89%88),原文链接markdown语法限制会跳错,没办法了,只能换成短连

接了。


UMD

即Universal Module Definition,应该算是AMD和commonjs的一个糅合。

其原理:先判断是否支持nodejs的模块(exports)是否存在,如果存在就是用nodejs模块模式,然后再判断

是否支持AMD(define是否存在),如果存在就使用AMD方式加载模块.


CMD

CMD 即Common Module Definition通用模块定义,CMD规范是国内发展出来的,就像AMD有个

requireJS,CMD有个浏览器的实现SeaJS(作者是国内大牛淘宝前端布道者玉伯),SeaJS要解决的问题和

requireJS一样,只不过在模块定义方式和

模块加载(可以说运行、解析)时机上有所不同
语法:Sea.js 推崇一个模块一个文件,遵循统一的写法
define:define(id?, deps?, factory)

因为CMD推崇:一个文件一个模块,所以经常就用文件名作为模块id

CMD推崇依赖就近,所以一般不在define的参数中写依赖,在factory中写

factory有三个参数:function(require, exports, module)
require是 factory 函数的第一个参数
require(id) 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口
exports 是一个对象,用来向外提供模块接口
module 是一个对象,上面存储了与当前模块相关联的一些属性和方法

demo
// 定义模块  myModule.js
define(function(require, exports, module) {
var $ = require('jquery.js')
$('div').addClass('active');
});

// 加载模块
seajs.use(['myModule.js'], function(my){

});


AMD,CMD 区别 

关于这两个的区别网上可以搜出一堆文章,简单总结一下

最明显的区别就是在模块定义时对依赖的处理不同
AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块
CMD推崇就近依赖,只有在用到某个模块的时候再去require

这种区别各有优劣,只是语法上的差距,而且requireJS和SeaJS都支持对方的写法
AMD和CMD最大的区别是对依赖模块的执行时机处理不同,注意不是加载的时机或者方式不同

很多人说requireJS是异步加载模块,SeaJS是同步加载模块,这么理解实际上是不准确的,其实加载模

块都是异步的,只不过AMD依赖前置,js可以方便知道依赖模块是谁,立即加载,而CMD就近依赖,需要

使用把模块变为字符串解析一遍才知道依赖了哪些模块,这也是很多人诟病CMD的一点,牺牲性能来带

来开发的便利性,实际上解析模块用的时间短到可以忽略。

为什么我们说两个的区别是依赖模块执行时机不同,为什么很多人认为ADM是异步的,CMD是同步的

(除了名字的原因。。。)
同样都是异步加载模块。

(1)AMD在加载模块完成后就会执行该模块,所有模块都加载执行完后会进入

require的回调函数,执行主逻辑,这样的效果就是依赖模块的执行顺序和书写顺序不一定一致,看网络速

度,哪个先下载下来,哪个先执行,但是主逻辑一定在所有依赖加载完成后才执行。

(2)CMD加载完某个依赖模块后并不执行,只是下载而已,在所有依赖模块加载完成后进入主逻辑,遇

到require语句的时候才执行对应的模块,这样模块的执行顺序和书写顺序是完全一致的。

这也是很多人说AMD用户体验好,因为没有延迟,依赖模块提前执行了,CMD性能好,因为只有用户需

要的时候才执行的原因。http://www.cnblogs.com/dolphinX/p/4381855.html


requirejs seajs

这两个分别是ADM,CMD的实现方案,肯定有异同。

(requirejs的应用示例:静态文件服务器devServer.js)。
相同之处:

两者都是模块加载器,倡导js模块化开发的理念。
不同之处:

(1)定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载

器。Sea.js 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 环境中。

(2)遵循的规范不同。RequireJS 遵循 AMD(异步模块定义)规范,Sea.js 遵循 CMD (通用模块定义)规

范。规范的不同,导致了两者 API 不同。Sea.js 更贴近 CommonJS Modules/1.1 和 Node Modules 规范。

(3)推广理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采

纳。Sea.js 不强推,采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。

(4)对开发调试的支持有差异。Sea.js 非常关注代码的开发调试,有 nocache、debug 等用于调试的插件。

RequireJS 无这方面的明显支持。

(5)插件机制不同。RequireJS 采取的是在源码中预留接口的形式,插件类型比较单一。Sea.js 采取的是通

用事件机制,插件类型更丰富。

引用seajs/seajs#277


什么是Webpack?

事实上它是一个打包工具,而不是像RequireJS或SeaJS这样的模块加载器,通过使用Webpack,能够像

Node.js一样处理依赖关系,然后解析出模块之间的依赖,将代码打包。(如该项目中使用的模块化和打

包工具webpack的配置文件webpack.config.js)。

webpak不仅支持打包,而且支持AMD 和 CommonJS 方式来做模块化开发,所以打算尝试一下webpack

来实现模块化。

 1

 





 
Owner


Seasons123 commented on
22 Jun

扩展阅读:
AMD规范文档 https://github.com/amdjs/amdjs-api/wiki/AMD

amdjs 的 require 接口文档 https://github.com/amdjs/amdjs-api/wiki/require

amdjs 的接口文档 https://github.com/amdjs/amdjs-api/wiki

RequireJS官网接口文档 http://www.requirejs.org/docs/api.html
模块系统 seajs/seajs#240

前端模块化开发的价值 seajs/seajs#547

前端模块化开发那点历史 seajs/seajs#588

CMD 模块定义规范 seajs/seajs#242

SeaJS API快速参考 seajs/seajs#266

从 CommonJS 到 Sea.js seajs/seajs#269
RequireJS和AMD规范 http://javascript.ruanyifeng.com/tool/requirejs.html

CommonJS规范 http://javascript.ruanyifeng.com/nodejs/commonjs.html

Javascript模块化编程 http://www.ruanyifeng.com/blog/2012/10/javascript_module.html

Javascript模块化编程 http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html
知乎 AMD 和 CMD 的区别有哪些? http://www.zhihu.com/question/20351507
JavaScript模块化开发 - CommonJS规范 http://www.feeldesignstudio.com/2013/09/javascript-module-pattern-commonjs

JavaScript模块化开发 - AMD规范 http://www.feeldesignstudio.com/2013/09/javascript-module-pattern-amd
模块化设计 http://baike.baidu.com/view/189730.htm

模块化 http://baike.baidu.com/view/182267.htm
 
Owner


Seasons123 commented on
22 Jun

阮老师的相关文集:

Javascript模块化编程(一):模块的写法
http://www.ruanyifeng.com/blog/2012/10/javascript_module.html
Javascript模块化编程(二):AMD规范
http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html
Javascript模块化编程(三):require.js的用法
http://www.ruanyifeng.com/blog/2012/11/require_js.html
 
Owner


Seasons123 commented on
22 Jun • 

edited 

关于各个模块规范的老底吕师兄写过一篇也很好:


 

 js模块化历程http://www.cnblogs.com/lvdabao/p/js-modules-develop.html 





 Seasons123 changed
the title from mst-关于模块化:CMD,AMD,UMD,commonjs,requirejs,seajs,webpack to mst-关于模块化:Commonjs, AMD, UMD, CMD,
Requirejs, seajs, webpack on 22 Jun




 Seasons123 changed
the title from mst-关于模块化:Commonjs, AMD, UMD, CMD, Requirejs, seajs, webpack to Commonjs, AMD, UMD, CMD, Requirejs,
seajs, webpack on 22 Jun




 Seasons123 changed
the title from Commonjs, AMD, UMD, CMD, Requirejs, seajs, webpack to mst-关于模块化:CommonJs, AMD/RequireJs,CMD/seajs,
UMD, webpack on 22 Jun




 Seasons123 changed
the title from mst-关于模块化:CommonJs, AMD/RequireJs,CMD/seajs, UMD, webpack to CommonJs, AMD/RequireJs,CMD/seajs,
UMD, webpack on 22 Jun

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: