深刻淺出requireJS-1

  咱們都知道,雖然咱們能夠經過原型和繼承來使javascript面向對象。可是,當js代碼和邏輯過多時,代碼的維護和擴展會變的很不方便。這時,nodejs作的很是好,可是在瀏覽器端模塊化的js編程一直都是個難題。而requireJS就是來幫助咱們解決這個問題的。requireJS遵循amd規範,因此讓咱們先了解下關於AMD規範的事情。javascript

1、AMD規範css

  AMD規範是瀏覽器端的模塊規範,它的全稱爲異步模塊定義。從名稱上看便知它是適合script tag的。也能夠說AMD是專門爲瀏覽器中JavaScript環境設計的規範。它吸收了CommonJS的一些優勢,但又不照搬它的格式。開始AMD做爲CommonJS的transport format 存在,因沒法與CommonJS開發者達成一致而獨立出來。它有本身的wiki 和討論組 。java

AMD設計出一個簡潔的寫模塊API:node

define(id?, dependencies?, factory);jquery

其中:git

  • id: 模塊標識,能夠省略。
  • dependencies: 所依賴的模塊,能夠省略。
  • factory: 模塊的實現,或者一個JavaScript對象。
id遵循CommonJS  Module Identifiers 。dependencies元素的順序和factory參數一一對應。
 
如下是使用AMD模式開發的簡單三層結構(基礎庫/UI層/應用層):
 
base.js
define(function() {
    return {
        mix: function(source, target) {
        }
    };
});

  

ui.jsgithub

define(['base'], function(base) {
    return {
        show: function() {
            // todo with module base
        }
    }
});

 

page.js編程

define([ 'base' ],  function (base) {
     return  {
         show:  function () {
             // todo with module base
         }
     }
});

 

data.jsapi

define({
     users: [],
     members: []
});

 

以上同時演示了define的三種用法
  1. 定義無依賴的模塊(base.js)
  2. 定義有依賴的模塊(ui.js,page.js)
  3. 定義數據對象模塊(data.js)
 
細心的會發現,還有一種沒有出現,即具名模塊
 
4,具名模塊
define( 'index' , [ 'data' , 'base' ],  function (data, base) {
     // todo
});

 

具名模塊多數時候是不推薦的,通常由打包工具合併多個模塊到一個js文件中時使用。
 
前面提到dependencies元素的順序和factory一一對應,其實不太嚴謹。AMD開始爲擺脫CommonJS的束縛,開創性的提出了本身的模塊風格。但後來又作了妥協,兼容了 CommonJS  Modules/Wrappings 。即又能夠這樣寫
 
5,包裝模塊
define( function (require, exports, module) {
     var  base = require( 'base' );
     exports.show =  function () {
         // todo with module base
     }
});

 

不考慮多了一層函數外,格式和Node.js是同樣的:使用require獲取依賴模塊,使用exports導出API。
 
除了define外,AMD還保留一個關鍵字require。 require 做爲規範保留的全局標識符,能夠實現爲 module loader,也能夠不實現。
 
目前,實現AMD的庫有 RequireJS 、 curl 、 Dojo 、 bdLoadJSLocalnet 、 Nodules 等。
也有不少庫支持AMD規範,即將本身做爲一個模塊存在,如 MooTools 、 jQuery 、 qwery 、 bonzo  甚至還有  firebug 。
2、CMD規範
  與AMD規範相似的還有CMD規範,
在CMD中,一個模塊就是一個文件,格式爲:
     define( factory );
 
    全局函數define,用來定義模塊。
    參數 factory  能夠是一個函數,也能夠爲對象或者字符串。
    當 factory 爲對象、字符串時,表示模塊的接口就是該對象、字符串。
 
    定義JSON數據模塊:
  1. define({ "foo": "bar" });
    經過字符串定義模板模塊:

  1. define('this is {{data}}.');
    factory 爲函數的時候,表示模塊的構造方法,執行構造方法即可以獲得模塊向外提供的接口。

  1. define( function(require, exports, module) { 
  2.     // 模塊代碼
  3. });


     define( id?, deps?, factory );
    define也能夠接受兩個以上的參數,字符串id爲模塊標識,數組deps爲模塊依賴:

  1. define( 'module', ['module1', 'module2'], function( require, exports, module ){
  2.     // 模塊代碼
  3. } );
    其與 AMD 規範用法不一樣。
 
     require 是 factory 的第一個參數。
    require( id );
    接受模塊標識做爲惟一的參數,用來獲取其餘模塊提供的接口:

  1. define(function( require, exports ){
  2.     var a = require('./a');
  3.     a.doSomething();
  4. });
 
    require.async( id, callback? );
    require是同步往下執行的,須要的異步加載模塊能夠使用 require.async 來進行加載:

  1. define( function(require, exports, module) { 
  2.     require.async('.a', function(a){
  3.         a.doSomething();
  4.     });
  5. });
    require.resolve( id )
    能夠使用模塊內部的路徑機制來返回模塊路徑,不會加載模塊。
 
     exports 是 factory 的第二個參數,用來向外提供模塊接口。

  1. define(function( require, exports ){
  2.     exports.foo = 'bar'; // 向外提供的屬性
  3.     exports.do = function(){}; // 向外提供的方法
  4. });
    固然也能夠使用 return 直接向外提供接口。

  1. define(function( require, exports ){
  2.     return{
  3.         foo : 'bar', // 向外提供的屬性
  4.         do : function(){} // 向外提供的方法
  5.     }
  6. });
    也能夠簡化爲直接對象字面量的形式:

  1. define({
  2.     foo : 'bar', // 向外提供的屬性
  3.     do : function(){} // 向外提供的方法
  4. });


    與nodeJS中同樣須要注意的是,一下方式是錯誤的:

  1. define(function( require, exports ){
  2.     exports = {
  3.         foo : 'bar', // 向外提供的屬性
  4.         do : function(){} // 向外提供的方法
  5.     }
  6. });


    須要這麼作

  1. define(function( require, exports, module ){
  2.     module.exports = {
  3.         foo : 'bar', // 向外提供的屬性
  4.         do : function(){} // 向外提供的方法
  5.     }
  6. });
    傳入的對象引用能夠添加屬性,一旦賦值一個新的對象,那麼值錢傳遞進來的對象引用就會失效了。開始之初,exports 是做爲 module.exports 的一個引用存在,一切行爲只有在這個引用上 factory 才得以正常運行,賦值新的對象後就會斷開引用,exports就只是一個新的對象引用,對於factory來講毫無心義,就會出錯。
 
    module 是factory的第三個參數,爲一個對象,上面存儲了一些與當前模塊相關聯的屬性與方法。
        module.id 爲模塊的惟一標識。
        module.uri 根據模塊系統的路徑解析規則獲得模塊的絕對路徑。
        module.dependencies 表示模塊的依賴。
        module.exports 當前模塊對外提供的接口。
相關文章
相關標籤/搜索