本節書摘來自異步社群《javascript架構設計》一書中的第2章,第2.4節,作者:司徒正美著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
我們再來看define方法,打個比方,它與require的關系就是内應外合。define是應,require是合。require擁有加載器90%的排程資源,以圍城姿态攻打我們封閉的javascript子產品。javascript子產品則由一個“内鬼”define來看守城門。當require送出請求,define就打開城門,子產品被兼并到mass framework的“龐大帝國内”!
define有3個參數,前面兩個為可選,事實上這裡的id沒什麼用,就是給開發者看的,它還是用getcurrentscript方法得到script節點路徑做id,deps沒有就補上一個空數組。在mass中,先根據浏覽器的情況對子產品進行分級,一些子產品是專門用于打更新檔的,隻對ie6、ie7、ie8有用,但對chrome沒有用,這個我們在require時就自動排除它。但合并後,我們不得不把它們都加上(因為不知道面對的是什麼浏覽器),mass設定一個參數,用于忽略執行這個更新檔子產品的工廠函數,保證架構用浏覽器的原生api執行。這個參數就設定在define中,為一個布爾,如果為true就跳過。
此外,define還要考慮循環依賴的問題。比如說加載a,要依賴b與c,加載b,要依賴a與c,這時a與b就循環依賴了。a與b在判定各自的deps中的鍵值都是2時才執行,結果都無法執行了。
define的源碼:
checkcycle方法:
define與require互相調用的示意如圖2.1所示。

▲圖2.1
至此整個加載器就完成了。現在的難點轉為我們如何判定目前子產品的加載情況,如何知道它的子產品名,如何排查它的對應的連結是否有效。為此mass動用一個modules對象,兩個數組(loadings與factory)。小小一個加載器,裡面的注釋就提及到許多相容性問題,真正與dom打交道還沒有開始呢!
最後看一下mass加載器,加載自己架構的ajax、node子產品一共做了多少事吧!
firefox20會加載這麼多子產品,如圖2.2所示。
▲圖2.2
ie10在ie7模式下會加載如下子產品,如圖2.3所示。
▲圖2.3
由于使用了子產品化,我們就可以分級,對舊版本ie使用體積更龐大的query子產品,其他則使用query_neo,并且多了許多更新檔子產品。
此外,mass加載器會把加載過程全部記錄下來,大家可以直接在firefox看到這些消息,如圖2.4所示。
▲圖2.4
子產品加載器會讓我們的前端開發變得更為工業化,維護調試都非常友善,強烈建立大家在工作時使用。現在國内主流的幾個加載器seajs、requirejs、mass、oyejs都是比較好的選擇。