对前端模块化amd和cmd的几点浅识

对前端模块化amd和cmd的几点浅识

前端模块化的几点浅识

前言:

9月份去希格玛大厦的一场面试,除了迟到,印象最深的应该是面试官提的这个问题—要我谈谈关于前端模块化的见解。当时耳朵听到我只是模糊还有这个印象,但是我也不敢乱说,就说了不太了解,面试官看我不太明白的样子,说你可以说说AMDCMD,我摇摇头表示只是听过。面试官说你不是用过angular吗,里面的“ng”就是模块化。但是我还是没能回答,面试官和善地对我说要我回去一定要好好学学这个,于是就有了这篇博客。

一、什么是模块化?什么是前端模块化?

模版化这个概念还是大二时候学习软件工程的书本概念:模块化是指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程,有多种属性,分别反映其内部特性。是一种处理复杂系统分解成为更好的可管理模块的方式。它可以通过在不同组件设定不同的功能,把一个问题分解成多个小的独立、互相作用的组件,来处理复杂、大型的软件。

通俗的讲就是任务分工,分责执行,尽量希望各个模块之间的低耦合,高聚合,使得可以允许不同程序员同时进行不同模块的开发工作。对于软件行业来说:解耦软件系统的复杂性,使得不管多么大的系统,也可以将管理,开发,维护变得“有理可循”。试想谷歌的几亿行代码如果不加以模块化开发和储存,一行代码的错误就可能导致整个系统巨大的运行错误。

模块化的概念最初就是传统软件行业的开发规范,随着现代前端内容的扩充,网站架构越来越大,前端代码也变得越来愈复杂。所以就引入了前端模块化这个概念,前端模块化的各种规范制度也就慢慢形成了,其中尤其以AMDAsynchronous Module Definition),CMDCommon Module Definition)这两个规范因为各自所属框架的推出而被广为人知。

二、AMD RequireJS

AMDAsynchronous Module Definition),字面意思是异步的模块定义,接触了JsAJAX的同学对AAsynchronous)这个异步的概念应该是很熟悉的了,在ADM规范中,所有的模块将被异步加载,彼此依赖的语句被放到了模块的回调函数中,模块加载不影响后面语句的运行。

看到这里,解释一下我之前关于js回调函数的小困惑。在这里可以这样简单的理解,回调就是一个函数的调用过程。模块函数有一个参数,这个参数是个另一个函数,当模块函数执行完以后执行这个参数函数。那么这个过程就叫回调。

AMD规范只定义了一个函数 "define",它是全局变量。函数的描述为

    define(id?, dependencies?, factory);

https://github.com/amdjs/amdjs-api/wiki/AMD-(中文版)

其中第一个参数id,是个字符串,定义的是模块的名字,这个参参数是可选的。如果没有传入该参数,模块的名字默认会定义为模块加载器请求的制定脚本的名字。如果提供了该参数,模块名必须是“顶级”的和唯一绝对的(不允许相对名字)。

第二个参数,dependencies(),需要传入定义模块所依赖的模块的数组字面量,依赖参数是可选的,如果忽略此参数,它应该默认为["require", "exports", "module"]。然而,如果工厂方法的形参个数小3,加载器会选择以函数指定的参数个数调用工厂方法。

第三个参数,工厂方法factory,为模块初始化要执行的函数或对象。如果为函数,应该只被执行一次。如果是对象,此对象为模块的输出值。

创建模块标识为 alpha 的模块,依赖于 require export,和标识为 beta 的模块  

RequireJs

    官网 http://www.requirejs.org/

    API http://www.requirejs.org/docs/api.html

RequireJs是一个前端的模块化管理的工具库,遵循AMD规范,它的作者就是AMD规范的创始人,所以说RequireJs是对AMD规范的阐述,也可以说AMDRequireJs在形成过程中的产出。

RequireJs的基本思想为:通过一个函数来将所有所需要的或者说所依赖的模块实现装载进来,然后返回一个新的函数(模块),我们所有的关于新模块的业务代码都在这个函数内部操作,其内部也可以无限制的使用预先定义好的要依赖的模块。

三、CMD seaJS

CMDCommon Module DefinitionCMD中,一个模块就是一个文件,格式为:

    define( factory );

全局函数define,用来定义模块。

参数 factory  可以是一个函数,也可以为对象或者字符串。

factory 为对象、字符串时,表示模块的接口就是该对象、字符串。

seaJS

    官网 http://seajs.org/docs/

    API快速参考 https://github.com/seajs/seajs/issues/266
    sea.js 核心特征:

        1. 遵循CMD规范,与NodeJS般的书写模块代码。

        2. 依赖自动加载,配置清晰简洁。

 

四、AMD CMD 区别到底在哪里?

看了以上 AMDrequireJS CMD seaJS的简单介绍会有点感觉模糊,总感觉较为相似。因为像 requireJS 其并不是只是纯粹的AMD固有思想,其也是有CMD规范的思想,只不过是推荐 AMD规范方式而已, seaJS也是一样。

下面是玉伯对于 AMD CMD 区别的解释:

AMD RequireJS 在推广过程中对模块定义的规范化产出。

CMD SeaJS 在推广过程中对模块定义的规范化产出。

这些规范的目的都是为了 JavaScript 的模块化开发,特别是在浏览器端的。

目前这些规范的实现都能达成浏览器端模块化开发的目的。

区别:

1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

2. CMD 推崇依赖就近,AMD 推崇依赖前置。虽然 AMD 也支持 CMD 的写法,同时还支持将 require 作为依赖项传递,但 RequireJS 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。

  3. AMD API 默认是一个当多个用,CMD API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 requireCMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹。

  4. 还有一些细节差异,具体看这个规范的定义就好,就不多说了。

另外,SeaJS RequireJS 的差异,可以参考:https://github.com/seajs/seajs/issues/277

总结

 下面的扩展阅读可以更好的帮助你理解模块化以及各个规范。

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 

模块系统 https://github.com/seajs/seajs/issues/240

前端模块化开发的价值 https://github.com/seajs/seajs/issues/547

前端模块化开发那点历史 https://github.com/seajs/seajs/issues/588

CMD 模块定义规范 https://github.com/seajs/seajs/issues/242

SeaJS API快速参考 https://github.com/seajs/seajs/issues/266

CommonJS Sea.js https://github.com/seajs/seajs/issues/269    

RequireJSAMD规范  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 



回复列表



回复操作






发布时间:2016-03-23 09:35:19

修改时间:2016-03-23 09:41:28

查看次数:539

评论次数:7

TA的文章总数

37