AMD/CMD/CommomJS规范

作者: 7天苹果 | 来源:发表于2017-08-18 14:34 被阅读98次

    在了解AMD,CMD/CommomJS规范前,我们先来简单地了解下什么是模块?

    简单的说,一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。当然,模块开发需要遵循一定的规范,否则各用各的就会乱套了。

    一、CommomJS

    CommonJS就是为JS的表现来制定规范,因为js没有模块的功能所以CommonJS应运而生,它希望js可以在任何地方运行,不只是浏览器中。

    Node,CommonJS,浏览器甚至是W3C之间有什么关系呢,找到了个贴切的图:

    image.png

    CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)} {模块标识(module)}

    require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身。

    比如说我们就可以这样用了:

    //sum.js
    exports.sum = function(){...操作..};
    
    //calculate.js
    var math = require('sum');
    exports.add = function(n){
     return math.sum(val,n);
    };
    

    虽说Node遵循CommonJS的规范,但是相比也是做了一些取舍,填了一些新东西的。


    二、AMD

    CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,为什么这么说呢?

    这需要分析一下浏览器端的js和服务器端js都主要做了哪些事,有什么不同了:

    image.png

    由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,于是乎,AMD(异步模块定义)出现,这种规范是异步的加载模块,requireJs应用了这一规范。先定义所有依赖,然后在加载完成后的回调函数中执行:AMD是依赖前置的,换句话说,在解析和执行当前模块之前,模块作者必须指明当前模块所依赖的模块。如

    define(['./a','./b'],function(a,b) {
         a.doSomething()
         b.doSomething()
    });
    

    代码一旦运行到此处,能立即知晓依赖。而无需遍历整个函数体找到它的依赖,因此性能有所提升,缺点就是开发者必须显式得指明依赖——这会使得开发工作量变大。比如,当你写到函数体内部几百上千行的时候,忽然发现需要增加一个依赖,你不得不回到函数顶端来将这个依赖添加进数组。

    AMD虽然实现了异步加载,但是开始就把所有依赖写出来是不符合书写的逻辑顺序的,能不能像commonJS那样用的时候再require,而且还支持异步加载后再执行呢?


    三、CMD

    CMD(Common Module Definition)更贴近 CommonJS Modules/1.1 和 Node Modules 规范,一个模块就是一个文件;它推崇依赖就近,想什么时候 require就什么时候加载,实现了懒加载(延迟执行 ) ;它也没有全局 require, 每个API都简单纯粹 。

    在 CMD规范中,一个模块就是一个文件。代码的书写格式如下:

    define(factory);
    

    factory 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数:require、exports 和 module

    define(function(require, exports, module) {
        var a = require('./a');
        a.doSomething();
        var b = require('./b');
        b.doSomething();
    });
    

    四、AMD与CMD的比较

    AMD和CMD最大的区别是对依赖模块的执行时机处理不同,而不是加载的时机或者方式不同,二者皆为异步加载模块。AMD依赖前置,js可以方便知道依赖模块是谁,立即加载;而CMD就近依赖,需要使用把模块变为字符串解析一遍才知道依赖了那些模块,这也是很多人诟病CMD的一点,牺牲性能来带来开发的便利性,实际上解析模块用的时间短到可以忽略。


    推荐链接:
    CommonJS规范
    Commonjs规范及Node模块实现

    相关文章

      网友评论

      本文标题:AMD/CMD/CommomJS规范

      本文链接:https://www.haomeiwen.com/subject/yfnorxtx.html