前言:
爲何咱們須要模塊化開發,模塊化開發的好處有哪些? 首先咱們先說一下非模塊化的開發方式帶來的弊端。 非模塊化開發中會致使一些問題的出現,變量和函數命名可能相同,會形成變量污染和衝突,而且出錯時候很難排查。耦合程度高,不符合軟件開發中的高內聚和低耦合的原則,因此咱們就能夠總結一下模塊化開發的好處了:
① 解決項目中的變量污染問題。
② 開發效率高,有利於多人協同開發。
③ 職責單一,方便代碼重用和維護 。
③ 解決文件依賴問題,無需關注引包順序 。javascript
覺得做爲服務器端的開發,不會通過網絡傳輸,因此包的加載幾乎都是瞬間完成的,只有加載完成了,才能執行操做,因此commonjs是同步的,nodejs就是實現了這種規範。html
有關規範的具體詳情,找了兩篇文章:
http://www.open-open.com/doc/view/f7df10bb81c347f79b436faa85dcfd81
http://blog.jobbole.com/49290/java
瀏覽器端的規範,由於全部的文件請求都要通過網絡傳輸,不少文件的加載會有不肯定因素存在爲了解決這個問題,瀏覽器端出來了這兩個規範。node
異步模塊定義規範(Asynchronous Module Definition)制定了定義模塊的規則,這樣模塊和模塊的依賴能夠被異步加載。這和瀏覽器的異步加載模塊的環境恰好適應(瀏覽器同步加載模塊會致使性能、可用性、調試和跨域訪問等問題)。具體規範連接在這裏:中文版 英文版 ,requireJs就是AMD規範的實現。jquery
requirejs的基本使用:
① 引入requirejs包,而且設置入口文件git
<script data-main='js/main' src='http://apps.bdimg.com/libs/require.js/2.1.9/require.min.js'></script>
② 定義主模塊 在main.js文件中github
define(['module1','module2',function(m1,m2) { // 說明:上面兩個module是依賴模塊,經過m1,m2的方式來使用 // 在這裏咱們寫本身的業務邏輯 todo // 若是咱們須要暴露出去,須要 return ,不是用exports或者module.exports // return {}; }]);
後續的使用,直接看文檔吧,之後有機會再來補充。
requirejs官網
requirejs中文官網編程
通用模塊定義 (Common Module Definition) 是 SeaJS 在推廣過程當中對模塊定義的規範化產出。相似的還有 CommonJS Modules/2.0 規範。
這些規範的目的都是爲了 JavaScript 的模塊化開發,特別是在瀏覽器端的。
目前這些規範的實現都能達成瀏覽器端模塊化開發的目的。有兩篇文檔相關文檔: 文檔1 文檔2 , 下面簡要說一下seajs, 詳細資料還得戳旁邊的資料文檔。json
seajs 的基本使用api
引入包文件
<script src='http://apps.bdimg.com/libs/seajs/2.3.0/sea.js'></script>
定義一個模塊,好比在這個文件 student.js 中
define(function(require,exports,module){ function Student(){ this.name = '張三'; } // 對外暴露該模塊的接口: module.exports = new Student(); })
使用模塊:經過 seajs.use()
來實現,第一個參數是使用模塊的路徑,第二個回調函數中的參數是所要使用模塊暴露出來的一個接口。
seajs.use('./student.js',function(stu){ console.log(stu.name); // 張三 });
seajs 暴露出接口的方式
module.exports
方式導出對象exports.屬性或方法
方式導出seajs 內部的異步加載簡單小demo — 寫個小demo來闡述一下這個異步加載機制,在demo中,有如下幾個文件 index.html ,loadJs.js ,module1.js:
index.html文件中的關鍵代碼
<!--引入cdn上的seajs文件--> <script src='http://apps.bdimg.com/libs/seajs/2.3.0/sea.js'></script> <script src='loadJs.js'></script> <script> loadJs('module1.js',function(){ console.log('回調內的函數最後執行'); }); </script>
loadJs.js文件中的代碼
function loadJs(path,callback) { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.setAttribute('src',path); head.appendChild(script); if(!/*@cc_on!*/false) { // 非IE瀏覽器 script.onload = function() { console.log('非IE瀏覽器'); callback(); } }else{ script.onreadystatechange = function(){ if(script.readyState === 'loaded' || script.readyState === 'complete') { console.log('IE'); callback(); } } } }
module1.js文件中的代碼:
console.log('我是module1文件內的');
在Chrome下測試,最後控制檯的輸出結果:
我是module1文件內的 非IE瀏覽器 回調內的函數最後執行
總結:在模塊加載的過程當中,先執行依賴模塊內的邏輯,最後再去執行回調函數內的邏輯
seajs 異步加載 require 中的async方法:
require.async() 方法用來在模塊內部異步加載模塊,並在加載完成後執行指定回調。callback 參數可選。 require 是同步往下執行,require.async 則是異步回調執行。require.async 通常用來加載可延遲異步加載的模塊。
seajs 的第三方依賴庫的引入:好比 jQuery,咱們須要使用jquery,加入到咱們的項目中,首先咱們須要對jquery 進行改造,在高版本的jquery文件好比2.2中支持amd規範但不支持cmd規範,在文件中的最後找到以下代碼:
if ( typeof define === "function" && define.amd ) { define( "jquery", [], function() { return jQuery; } ); }
咱們把它改造爲:
if ( typeof define === "function" && (define.amd || define.cmd) ) { define( "jquery", [], function() { return jQuery; } ); }
而後咱們能夠經過加載模塊的方式,把jQuery加載進去了。
seajs的配置調試:
簡單的寫一寫:
seajs.config({
// 別名配置 alias: { 'es5-safe': 'gallery/es5-safe/0.9.3/es5-safe', 'json': 'gallery/json/1.0.2/json', 'jquery': 'jquery/jquery/1.10.1/jquery' }, // 路徑配置 paths: { 'gallery': 'https://a.alipayobjects.com/gallery' } })
經過對 sea.js 進行配置,讓模塊編寫、開發調試更方便。
seajs 中的module
— 引自 玉伯
- 二者定位有差別。RequireJS 想成爲瀏覽器端的模塊加載器,同時也想成爲 Rhino / Node 等環境的模塊加載器。SeaJS 則專一於 Web 瀏覽器端,同時經過 Node 擴展的方式能夠很方便跑在 Node 服務器端。
- 二者遵循的標準有差別。RequireJS 遵循的是 AMD(異步模塊定義)規範,SeaJS 遵循的是 CMD (通用模塊定義)規範。規範的不一樣,致使了二者 API 的不一樣。SeaJS 更簡潔優雅,更貼近 CommonJS Modules/1.1 和 Node Modules 規範。
- 二者社區理念有差別。RequireJS 在嘗試讓第三方類庫修改自身來支持 RequireJS,目前只有少數社區採納。SeaJS 不強推,而採用自主封裝的方式來「海納百川」,目前已有較成熟的封裝策略。
- 二者對調試等的支持有差別。SeaJS 經過插件,能夠實現 Fiddler 中自動映射的功能,還能夠實現自動 combo 等功能,很是方便便捷。RequireJS 無這方面的支持。
- 二者的插件機制有差別。RequireJS 採起的是在源碼中預留接口的形式,源碼中留有爲插件而寫的代碼。SeaJS 採起的插件機制則與 Node 的方式一致:開放自身,讓插件開發者可直接訪問或修改,從而很是靈活,能夠實現各類類型的插件。插件開發者可直接訪問或修改,從而很是靈活,能夠實現各類類型的插件。
- 對於依賴的模塊,AMD 是提早執行,CMD 是延遲執行。不過 RequireJS 從 2.0 開始,也改爲能夠延遲執行(根據寫法不一樣,處理方式不一樣)。CMD 推崇 as lazy as possible.
- CMD 推崇依賴就近,AMD 推崇依賴前置。