天天看點

Seajs源碼解析系列(一)

前言:以前在做webgis開發的時候,就對dojo的子產品化加載方式很好奇,一直想弄清楚它的實作原理,奈何其架構過于龐大,加上自己也懶,就一直沒有深入進行研究。這段時間接觸了Sea.js,淘寶前端大牛玉伯寫的。它遵循的是CMD的加載規範,據說可以像Node一樣書寫子產品代碼。好奇看了一下源碼,嗯~,才1000來行,加上最近時間也不是太忙,就想深入研究一下。

Seajs簡介:

Seajs可以了解為是一種子產品加載器,可以提供一種簡單,友善的子產品化加載方式。以前,我們在前端開發過程中,通過會使用script标簽加載我們需要引入的js檔案。随着網頁的結構越來越複雜,我們需要引入的js檔案也越來越多,有的檔案之間甚至還有依賴關系,如果我們還像以前一樣将所有的代碼都放在一個檔案中的時候,很容易出現以下問題:

  • 全局變量互相影響
  • JavaScript檔案過大,影響下載下傳速度
  • 結構混亂,很難維護
  • 引入檔案時需要注意其依賴關系,稍不留神可能就會發生錯誤

在這種情況下,Seajs應運而生。Sea.js 是一個成熟的開源項目,核心目标是給前端開發提供簡單、極緻的子產品化開發體驗。這裡不多做介紹,有興趣的可以通路 seajs.org 檢視官方文檔。

使用 Sea.js,在書寫檔案時,需要遵守 CMD (Common Module Definition)子產品定義規範。一個檔案就是一個子產品。那麼,使用Seajs有什麼好處呢?再次回到我們上面的問題,假如我們在開發過程中,常常會将一些基礎的、底層的功能抽象出來,獨立成一個函數,并将其放在一個基礎的函數庫中,例如util.js。

function each(){}
function error(){}
           

那麼,我們以後再開發過程中如果需要使用這些功能,就可以在項目中引入util.js檔案,然後直接使用。這樣看起來很友善,但是在項目的進行中,我們常常會遇到這樣的問題,假如在頁面中我也想自定義一個方法來周遊對象,但是在util.js中已經有一個了,那我的方法就隻能取其他的名字。當方法名越來越多的時候,對于我這種英語剛過四級的學渣來說,取名簡直是一種煎熬/(ㄒoㄒ)/~~。。。

另外,還有一個問題,假如我的util.js中的某個方法還依賴于baseUtil.js檔案,那麼我們在引入js檔案的時候就必須要這樣:

<script type="text/javascript" src="baseUtil.js"></script>
    <script type="text/javascript" src="util.js"></script>
           

假如我們在開發過程中,忘記了依賴引入,項目中的代碼功能可能就會報錯。

以上的問題,我相信大部分前端開發者都曾遇到過。那麼,我們如何通過Seajs的子產品化開發來解決上述問題呢?

Seajs在使用過程中,需要遵守CMD規範,一個檔案就是一個子產品,那麼,我們可以這樣定義我們util子產品。

define(function(require,exports,module){
    exports.each=function(){};
    exports.error=function(){};
})
           

那麼,我們在開發過程中要如何使用我們util子產品呢?例如,我們需要在前端定義一個module子產品,并在其中使用util中的功能。那麼,我們的module子產品就可以這樣寫:

define(function(require,exports){
    var util=require("./util.js");
    exports.init=function(){};
})
           

在這裡,我們通過require(“./util.js”)可以拿到util子產品通過exports暴露的接口。在這裡,我們可以将require了解為Seajs為我們提供的關鍵字,通過他,我們可以擷取其他子產品提供的接口。

通過以上的介紹,我們可以大緻的了解了Seajs帶來的兩個好處:

  • 通過exports暴露接口,解決了命名沖突的問題
  • 通過require引入依賴,使檔案的依賴關系内置,開發者隻需要關心自己目前使用的子產品,其他事情Seajs會幫你做好,提高了開發效率。

至此,Seajs的介紹已基本結束,前往Seajs官網可以了解更多有關seajs的知識。在下一節,将會和大家進一步分享這幾天閱讀Seajs源碼的心得體會。

繼續閱讀