原生/CommonJS /AMD/UMD 模塊化詳解

模塊化

模塊化已經是現代前端開發中不可或缺的一部分了把複雜的問題分解成相對獨立的模塊,這樣的設計可以降低程序複雜性,提高代碼的重用,也有利於團隊協作開發與後期的維護和擴展
ECMAScript2015 開始引入了模塊的概念,我們稱爲:ECMAScript Module,簡稱:ESM

模塊化的核心

  • 獨立的作用域
  • 如何導出模塊內部數據
  • 如何導入外部模塊數據

ESM

ECMAScript2015/ECMAScript6 開始,JavaScript 原生引入了模塊概念,而且現在主流瀏覽器也都有了很好的支持

獨立模塊作用域

一個文件就是模塊,擁有獨立的作用域,且導出的模塊都自動處於 嚴格模式下,即:'use strict'

原生

靜態模式
import必須放在模塊化代碼的最頂層 放點擊事件裏不行 這種方式叫靜態導入,不支持延遲加載

import b from "./b.js"  //正常情況導出 
    console.log(b)

b.js文件 導出

export default "這是b文件的內容"

使用
module告訴他是個模塊

<script type="module" src="./js/a.js"></script>    

動態方式導入

    // 動態導入  異步加載
    document.onclick = async function(){  //
      let b = await import ("./b.js")    //類似懶加載
        console.log(b.default)
    }

CommonJS 後端

在早起前端對於模塊化並沒有什麼規範,反而是偏向服務端的應用有更強烈的需求,CommonJS 規範就是一套偏向服務端的模塊化規範,NodeJS 就採用了這個規範。

// 導出
module.exports = {
    val:"這是b模塊導出的內容",
    vals:"這是b模塊導出的內容2"
}
//導入 模塊化在後端的寫法

let b = require('./b.js')
console.log(b)
// 在終端輸入 node a 輸出  {val:這是b模塊導出的內容}
console.log(b.vals) // 輸出  這是b模塊導出的內容2

AMD

因爲 CommonJS 規範一些特性(基於文件系統,同步加載),它並不適用於瀏覽器端,所以另外定義了適用於瀏覽器端的規範 ,我們可以通過一些第三方庫來解決

獨立模塊作用域
通過一個 define 方法來定義一個模塊,並通過該方法的第二個回調函數參數來產生獨立作用域
就是通過define導出導入 (解決代碼規範的問題)

//使用 define導入 需要參數 不需返回值
define([  //參數1 導入的路徑  是個數組形式 可寫多個
    './js/b.js',
], function(require) {//參數2:函數,參數存放導入的數據
    console.log(require)
    
});
// define導出 需要返回值 不需要參數 
define(function(){
    let val = "這是amd規範下的數據";
        return val
})
  <!--data-main當前主入口             三方庫網絡路徑 -->
    <script data-main='./js/a.js' src="https://cdn.bootcss.com/require.js/2.3.6/require.min.js"></script>

UMD導出

嚴格來說,UMD 並不屬於一套模塊規範,它主要用來處理 CommonJSAMDCMD 的差異兼容,是模塊代碼能在前面不同的模塊(原生/node/AMD)環境下都能正常運行
哪裏調用哪裏傳參
導入要遵守當前模塊(原生/node/AMD)環境 導入較爲簡單一般不需要處理

// UMD包含以上三種模式 以此滿足各種條件下的導出情況
// ()()匿名函數的自調用  (匿名函數的定義)(調用 需要的參數)
(function(factory){
    // module是不是對象                     module.exports是不是對象
    if (typeof module === "object" && typeof module.exports === "object") {
        //條件滿足說明是後端 Node, CommonJS-like 方式導出
        module.exports = factory; //不需要調用,哪裏使用,哪裏調用
    }else if (typeof define === "function" && define.amd) {
      	//說明是 AMD 模塊環境下 
          define(function(){
              return factory
          });
  }else{ //就是全局 原生
      window.rmb = factory
  }
}) (function (val){ //自定義過濾器
    return '$' +(val/100)  .toFixed(1)
   })
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章