1. 程式人生 > >前端模塊化 CommonJS AMD ES6 CMD

前端模塊化 CommonJS AMD ES6 CMD

date 分享圖片 image require 別名 fill app this com

不使用模模塊化的情況

  • util.js(基礎函數庫) getFormatDate 函數
  • a-util.js(業務基礎函數庫) aGetFormatDate 函數 使用getFormatDate
  • a.js aGetFormatDate

  • // util.js
    function getFormatDate(date, type) {
        // type === 1 返回 xxxx
        // type === 2 返回 xxx
        // ...
    }
    
    // a-util.js
    function aGetFormatDate(date) {
        //要求返回 xxx 格式
    return getFormatDate(date, 2) } // a.js var dt = new Date() console.log(aGetFormatDate(dt)) <script src="util.js"></script> <script src="a-util.js"></script> <script src="a.js"></script>

    這些代碼中的函數必須是全局變量,才能暴露給使用方,全局變量汙染
  • a.js知道要引用a-util.js,但是他還知道要依賴util.js麽?

使用模塊化

// util.js
export {
    function getFormatDate(date, type) {
    // type === 1 返回 xxxx
    // type === 2 返回 xxx
    // ...
    }
}

// a-util.js
var getFormateDate require(‘util.js‘)
export {
    function aGetFormatDate(date) {
    //要求返回 xxx 格式
    return getFormatDate(date, 2)
    }
}

// a.js var aGetFormatDate = require(‘a-util.js‘) var dt = new Date() console.log(aGetFormatDate(dt))

  • 直接<script src="a.js"></script>,其他根據依賴關系自動引用
  • 那兩個函數,沒必要做成全局變量,不會帶來汙染和覆蓋

AMD(異步模塊定義)

  • require.js requirejs.org
  • 全局define函數
  • 全局require函數
  • 依賴JS會自動、異步加載

//util.js
define(function () {
    return {
        getFormatDate(date, type) {
    // type === 1 返回 xxxx
    // type === 2 返回 xxx
    // ...
    }
    }
})

// a-util.js
define([‘./util.js‘], function (util) {
    return {
        aGetFormatDate: function(date) {
            return util.getFormatDate(date,2)
        }
    }
})

// a.js
define([‘a-util.js‘], function (aUtil) {
    return {
        printDate: function(date) {
            console.log(aUtil.aGetFormatDate(date))
        }
    }
})

// main.js
required([‘./a.js‘], function(){
    var date = new Date()
    a.printDate(date)
})

使用require.js
<scritp src="/require.min.js" data-main="./main.js"></scritp>

require()函數在加載依賴函數的時候是異步加載的,這樣瀏覽器不會失去響應,它指定的回調函數,只有前面的模塊加載成功,才會去執行。
因為網頁在加載js的時候會停止渲染,因此我們可以通過異步的方式去加載js,而如果需要依賴某些,也是異步去依賴,依賴後再執行某些方法。

CommonJS

  • nodejs 模塊化規範,現在被大量用於前端
  • 其那段開發依賴的插件和庫,都可以從npm中獲取
  • 構建工具的高度自動化,使得使用npm的成本非常低
  • CommonJS不會異步加載JS,而時同步一次性加載出來
// util.js
module.exports = {
    getFormatDate(date, type) {
    // type === 1 返回 xxxx
    // type === 2 返回 xxx
    // ...
    }
}

// a-util.js
var util = require(‘util.js‘)
module.exports = {
    aGetFormatDate: function(date) {
            return util.getFormatDate(date,2)
        }
}

AMD 和 CommonJS 的使用場景

  • 需要異步加載JS,使用AMD
  • 使用了npm之後建議使用CommonJS

    ES6實現模塊化

    技術分享圖片

    如果使用es6語法,那麽則無需引入requireJS進行模塊化,它的特點主要為:

    • 在模塊頂級作用域中的this為undefine。
    • 單個文件為一個模塊,頂級作用域聲明的變量只在當前模塊生效。對其他模塊不影響, 對外導出的變量才能被其他變量使用

    定義

    導出內容有倆種關鍵字:

    • export 導出該模塊要導出的變量、函數、對象等等。
    export const color = ‘#fff‘;

    • as 輸出時創建別名,也適用於導入情況。
    const color = ‘#fff‘;
    export color as white

    • export default 該模塊的默認輸出值,可以為變量、函數、對象,一個模塊只能導出一個默認值。默認導出的內容可以無名稱,因為默認導出就代表該模塊,但也可以有名稱,或者使用別名 as。
    export default const color = ‘#fff‘;
    // export default 5;
    // const color = ‘#fff’;
    // export { color as default  }

    使用

    • 在模塊中使用import關鍵字來導入其他模塊導出的內容。 分為幾種情況:

    • 導入非默認內容,需要用結構的方式,因為在模塊中,非默認導出的內容,都會被添加到一個變量中,用結構的方式拿出一個或多個內容。

    import { color } from ‘./color‘;

    • 導入默認內容,可以直接導出即可。
    import color from ‘./color‘;

    CMD

    CMD規範的實現代表是sea.js

    • 對於依賴的模塊AMD是提前執行,CMD是延遲執行。不過RequireJS從2.0開始,也改成可以延遲執行(根據寫法不同,處理方式不通過)。

    • CMD推崇依賴就近,AMD推崇依賴前置。

    //AMD
    define([‘./a‘,‘./b‘], function (a, b) {
     
        //依賴一開始就寫好
        a.test();
        b.test();
    });
     
    //CMD
    define(function (requie, exports, module) {
         
        //依賴可以就近書寫
        var a = require(‘./a‘);
        a.test();
         
        ...
        //軟依賴
        if (status) {
         
            var b = requie(‘./b‘);
            b.test();
        }
    });

    簡單來說,就是sea.js屬於懶加載,require.js屬於預加載.

     

前端模塊化 CommonJS AMD ES6 CMD