前端模組化,AMD和CMD的區別總結

Super Mouse發表於2019-02-28

AMD和CMD都是瀏覽器端的js模組規範,2者的區別總結如下:

1、AMD推崇依賴前置,CMD推崇就近依賴

//AMD: mod.js
define([`dependency1`, `dependency2`], function(require, exports, module){
    //TODO

    module.exports = {};
});
複製程式碼
//CMD: mod.js
define(function(require, exports, module) {
    var $ = require(`jquery.js`)
    
    if(true) {
        let a = require(`./a.js`);
        //TODO
    }
    
    module.exports = {}
});
複製程式碼

這種區別各有優劣,只是語法上的差距,而且requireJS和SeaJS都支援對方的寫法

2、執行時機不同:AMD是載入完立即執行,CMD是延遲執行(二者的最大區別)

立即執行比較好理解,我們來看CMD的延遲執行。
還是以上面程式碼為例

//CMD: mod.js
define(function(require, exports, module) {
    var $ = require(`jquery.js`)
    
    if(true) {
        let a = require(`./a.js`);
        //TODO
    } else{
        let b = require(`./b.js`);
        //TODO
    }
    
    module.exports = {}
});
複製程式碼

在執行mod.js前,模組被解析為了字串,然後通過正規表示式找出了模組中所有的依賴並去一一載入,如例子中的jquery.js、a.js和b.js。但是載入後的依賴並不立即執行,而是當js執行到require語句的時候才被執行。如例子中的juery.js和a.js會按執行順序依次執行,而b.js因為是在條件控制的else裡,所以它永遠不會被執行。
需要說明一點的是,CMD這種用正則匹配字串中依賴的行為會影響效能,這也是被大家詬病的。

3、實現按需載入的方法不同

兩種規範都可以實現按需載入,但是實現的API不同:

//AMD:
define(function(require, exports, module){
    document.getelementById(`app`).onclick = function() {
        require([`myModule`], function (my){
            my.printName();
        });
    }
    //TODO
    module.exports = {};
});

複製程式碼
//CMD:
define(function(require, exports, module){
    document.getelementById(`app`).onclick = function() {
        require.async(`myModule`, function (my){
            my.printName();
        });
    }
    //TODO
    module.exports = {};
});
複製程式碼

相關文章