1. 程式人生 > >學習前端模組化方案的一些總結

學習前端模組化方案的一些總結

今天看了一天的前端的模組化的解決方案,發現如果是初學者會有很多的疑問,網上看了很多文章漸漸才有了頭緒。

首先模組化的方案其實一直都用,從我們最基本的函式來說可以說就是一個模組化的過程,可是這個模組化的過程會有很多的弊端,首先就是變數衝突的問題,命名衝突的問題,全域性作用域的汙染,一旦專案構建的越來越大,會導致我們越來越痛苦,所以出現了很多的解決方案,模組化就是目前比較流行的一種方法,es6出來完全就實現了模組化的工程,可以說模組化是一個優秀的前端人員必須學習的。

模組化的話首先要講commonJS它是伺服器端的node最先採用的一種模組化的規範,學習node的人肯定都明白,我沒有深入學習過,所以在這就不多說了。模組話固然是非常好的,但是在瀏覽器端實現起來確困難重重,首先是因為瀏覽器的環境中依賴的資源都是通過網路請求過來的,沒有服務端的那麼穩定,我們在請求資源時,資源可能對應在不同的伺服器端配置,所以會出現各種的問題,但是後面出現了一些改進的方案,先不急,先了解以下AMD規範和CMD規範。

在瞭解之前先來看一張圖這裡寫圖片描述
看了這幅圖之後,相信你會有一個大概的印象,AMD是非同步載入模組的縮寫,他產生了requireJS這樣的定義,CMD他有了seaJS這樣的模組載入框架,有一段程式碼很好的講了他們兩的區別:

// CMD
define(function(require, exports, module) {
  var a = require('./a')
  a.doSomething()
  // 此處略去 100 行
  var b = require('./b') // 依賴可以就近書寫
  b.doSomething()
  // ... 
})

// AMD 預設推薦的是
define(['./a'
, './b'], function(a, b) { // 依賴必須一開始就寫好   a.doSomething()   // 此處略去 100 行   b.doSomething()   ... })

requireJS需要在定義之前就要預載入所有需要的模組,而reaJS需要在什麼時候使用,什麼時候再進行載入,用語言來類比就是一個是靜態載入,一個是執行時載入,當然這個比喻不是很恰當,但是有些類似,下面說說在requireJS下定義模組的方式:
AMD其實也就只定義了一個define函式,

define(id?, dependencies?, factory);

這個函式就是定義模組的函式,引數說明:id就是這個模組的名字,也就是模組載入器要進行載入的指定的名字,在另外一個地方看到說也就是這個檔案的路徑名,第二個引數是當前模組已定義的依賴模組的陣列字面量,依賴引數是可選的,如果忽略此引數,預設是["require", "exports", "module"]


然而如果工廠方法的長度屬性小於三,載入器會以函式的長度屬性指定的引數屬性呼叫工廠方法。
工廠方法factory是模組初始化要執行的函式或物件,如果為函式,他應該只被執行一次,如果為物件,他應該為模組的輸出值,定義模組用define定義用exports匯入,下面來看一個例子:

 define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
       exports.verb = function() {
           return beta.verb();
           //Or:
           return require("beta").verb();
       }
   });

這就是定義一個模組的方法,我們常見的jquery就已經實現自動模組化了,

seajs.config({

'base':'/',

'alias':{

    'jquery':'jquery.js'//定義jQuery檔案

}
});
define(function(require, exports, module{

     //先要載入jQuery的模組

     var $ = require('jquery');

     //然後將jQuery物件傳給外掛模組

     require('./cookie')($);

     //開始使用 $.cookie方法

});

seaJS是懶載入,那麼它是怎麼使用的,下面看個例子:

 - 引入sea.js的庫
 - 如何變成模組?
      - define
 - 3.如何呼叫模組?
      -exports
      -sea.js.use
 - 4.如何依賴模組?
      -require

 <script type="text/javascript">
        define(function (require,exports,module) {
            //exports : 對外的介面
            //requires : 依賴的介面
            require('./test.js');//如果地址是一個模組的話,那麼require的返回值就是模組中的exports
        })
</script> 

就這樣可以使用響應的模組了,當然對於這些規範有一些很深的思考,比如怎麼設計一個AMD模組,怎麼實現,這些我暫時沒有實踐過,暫時不說了。