1. 程式人生 > >模組化機制

模組化機制

模組化

前端專案日益龐大,涉及到的業務方面越來越多,現在比較流行的是元件化開發,剩下就是模組化、工程化了。最新的ES6頁支援了類class和模組module屬性;對於模組化一直以來都不是特別清楚,趁機記錄一下。

1.什麼是JavaScript模組化

  • 什麼是模組化?

    模組化,簡單來說就是:在解決一個複雜問題或者一系列雜糅問題時,按照一種查分的思維吧問題進行系統性分解,分而劃之進行處理。程式碼模組化,就是將複雜系統程式碼分解為結構更加合理、可維護性更高、便於管理的子模組的方式。對於軟體行業來說,高內聚、低耦合的軟體程式碼結構,使得不管系統的程式碼結構大小、業務的複雜性差異多大,系統都具有方便的管理性、開發敏捷性、高度可維護性。

  • 如何做到模組化設計

    模組化的設計的基本標準是分解、依賴、聚合,一個模組化系統必然具備以下幾個特點:
    ①定義封裝的模組;②定義新模組對其他模組的依賴;③對其他模組引入的支援;

2.實際場景中的模組化實現

弄清了模組化的原理,那麼實際開發中我們如何運用這一設計模式,總要有一個或幾個規範標準形式,這樣才能統一大家的程式碼。JavaScript中出現了一些非傳統開發方式的模組化規範:CommonJSAMDCMD.
看到眼花繚亂的AMD、CMD、UMD、sealJS、RequireJS、CommonJS經常讓前端同學不知所措,開發過程中也是bug頻頻,這些都是什麼意思,又有什麼區別那,下面來進行一一說明。

2.1. CommonJS————同步載入、伺服器端的模組化規範,採用案列:Node.js
  • 實現原理:
    • 一個單獨的檔案就是一個模組;
    • 載入模組採用同步方式,載入完成後才能執行後面的操作
    • 載入模組使用require方法,該方法讀取一個檔案並執行,最後返回內部的exports物件;
  • 特點:
    • 由於是同步載入。所以載入、執行完依賴檔案後,才可執行後續的操作,即會產生同步阻塞;
    • 比較適合運用於伺服器的程式設計,載入模組檔案通常都存在本地磁碟,載入過程無延遲,無需非同步載入;
      由於同步載入執行,存在同步阻塞問題,對於從遠端伺服器載入模組的瀏覽器環境不友好,
  • 栗子:
//lib.js
var privateVar=123; //區域性變數 function funs(){ //公有方法 this.foo=fucntion(){//do something}; this.bar=function(){//do other things }; } exports.funs=new funs(); // exports輸出物件上的方法是公有方法
//require方法預設讀取js檔案,通常省略.js字尾
var funs=require(''./lib').funs;
funs.foo();
2.2 AMD————非同步載入,採用案例:require.js
  • 實現原理: ‘Ansychronous Module Definition’–非同步模組定義
    • 通過一個函式封裝所有所需要、所依賴的模組/方法/物件/屬性;返回一個新函式(模組);
    • 推崇依賴前置,依賴的模組提前執行;(require2.0開始支援延遲執行)
    • 採用依賴注入方式載入模組;
    • 注入依賴模組後,執行非同步回撥函式;
  • 特點:
    • 非同步載入,不會產生非同步阻塞,適合瀏覽器網路環境;
    • 同時允許非同步載入、按需載入模組
  • 栗子:
    • 定義模組:define(id?,dependencies?,factory)
      ①id:模組標識,可選引數,字串型別;②dependencies:當前模組的依賴模組標識,可選引數,陣列型別;③factory:一個需要進行例項化的函式或者一個物件;
// 1. 定義無需依賴的模組
define({
  name:'jack';
  say:function(sex){ return `I am a ${sex}` }
})
// 2.定義有依賴的模組
define(['depModule'],fucntion(dep){
 return {
    varb:fucntion(){
      return dep.verb()+1;
    }
  }
})
// 3.定義具名模組
define('allDep',['depModuleA','depModuleB'],fucntion(depA,depB){
  export.varb=function(){
    return depA.fn();
  }
})
  • 載入模組:require([module],callback)
    ①[module]:需要載入的模組,陣列型別;②callback:回撥函式

    //
    require(['math'],fucntion(){
    math.add(arguments);
    })
2.3 CMD————非同步載入、非同步執行依賴,案例:SealJS

CMD 與 AMD 類似;都是採用非同步載入,不同點主要有一下幾點:
- 對依賴模組的執行時機:CMD延遲執行,AMD提前執行(RequireJS2.0後支援延遲執行)
- 依賴位置:CMD推崇依賴就近,按需載入;AMD推崇依賴前置;
- API:CMD推崇職責單一,AMD裡面require分區域性和全域性方式;

2.4 UMD———非同步載入,非同步執行,相容伺服器、瀏覽器端,是AMD和CommonJS的糅合

AMD 以瀏覽器第一的原則,非同步載入模組,載入的模組需經過包裝;
CommonJS模組以伺服器第一的原則,同步載入模組,載入的模組無需包裝;
UMD :(Universal Module Definition)跨瀏覽器、伺服器平臺解決方案

  • 原理:
    • 首先判斷是否支援Node.js模組(exports是否存在),存在則使用同步載入方案;
    • 再判斷是否支援AMD(define是否存在),存在則是用非同步載入方案
(function(){
  if( typeof exports==='object'){
    module.exports=factory();
  }else if (typeof define==='function' && define.amd){
      define(factory);
  }else{
    windoe.eventUtil=factory();
  }
})(this,function(){
// module ...  
})