模組化機制
模組化
前端專案日益龐大,涉及到的業務方面越來越多,現在比較流行的是元件化開發,剩下就是模組化、工程化了。最新的ES6頁支援了類
class
和模組module
屬性;對於模組化一直以來都不是特別清楚,趁機記錄一下。
1.什麼是JavaScript模組化
什麼是模組化?
模組化,簡單來說就是:在解決一個複雜問題或者一系列雜糅問題時,按照一種查分的思維吧問題進行系統性分解,分而劃之進行處理。程式碼模組化,就是將複雜系統程式碼分解為結構更加合理、可維護性更高、便於管理的子模組的方式。對於軟體行業來說,高內聚、低耦合的軟體程式碼結構,使得不管系統的程式碼結構大小、業務的複雜性差異多大,系統都具有方便的管理性、開發敏捷性、高度可維護性。
如何做到模組化設計
模組化的設計的基本標準是分解、依賴、聚合,一個模組化系統必然具備以下幾個特點:
①定義封裝的模組;②定義新模組對其他模組的依賴;③對其他模組引入的支援;
2.實際場景中的模組化實現
弄清了模組化的原理,那麼實際開發中我們如何運用這一設計模式,總要有一個或幾個規範標準形式,這樣才能統一大家的程式碼。JavaScript中出現了一些非傳統開發方式的模組化規範:
CommonJS
、AMD
、CMD
.
看到眼花繚亂的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 ...
})