2011-11-15 69 views
171

我想加載Backbone和Underscore(以及jQuery)與RequireJS。使用Backbone和Underscore的最新版本,似乎有點棘手。首先,Underscore自動將自己註冊爲一個模塊,但Backbone假定Underscore在全球範圍內可用。我還應該注意到Backbone似乎並沒有將自己註冊爲一個與其他庫不一致的模塊。這是我能想出的作品最好的main.js:使用RequireJS加載骨幹和下劃線

require(
{ 
    paths: { 
     'backbone': 'libs/backbone/backbone-require', 
     'templates': '../templates' 
    } 
}, 
[ 
    // jQuery registers itself as a module. 
    'http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js', 

    // Underscore registers itself as a module. 
    'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.2.1/underscore-min.js' 
], function() { 

    // These nested require() calls are just due to how Backbone is built. Underscore basically says if require() 
    // is available then it will automatically register an "underscore" module, but it won't register underscore 
    // as a global "_". However, Backbone expects Underscore to be a global variable. To make this work, we require 
    // the Underscore module after it's been defined from within Underscore and set it as a global variable for 
    // Backbone's sake. Hopefully Backbone will soon be able to use the Underscore module directly instead of 
    // assuming it's global. 
    require(['underscore'], function(_) { 
     window._ = _; 
    }); 

    require([ 
     'order!http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js', 
     'order!app' 
    ], function(a, app) { 
     app.initialize(); 
    }) 
}); 

我應該指出的是,雖然它的工作原理,優化扼流圈就可以了。我收到以下內容:

Tracing dependencies for: main 
js: "/home/httpd/aahardy/requirejs/r.js", line 7619: exception from uncaught JavaScript throw: Error: Error: Error evaluating module "undefined" at location "/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js": 
JavaException: java.io.FileNotFoundException: /home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js (No such file or directory) 
fileName:/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js 
lineNumber: undefined 
http://requirejs.org/docs/errors.html#defineerror 
In module tree: 
    main 

有沒有更好的處理方法?謝謝!

+0

你使用任何教程做它嗎? – kaha

+1

我瀏覽了http://backbonetutorials.com/organizing-backbone-using-modules/等各種教程,但它們似乎已經過時了最新版本的下劃線和主幹。 – Aaronius

+0

我還發現requirejs很難與其他庫一起使用,反之亦然。這就是爲什麼我創建了一個使用起來更容易,並且使用角度進行測試的庫。底部有一個演示應用程序:http://gngeorgiev.github.io/Modulerr.js/您也可以將所有腳本組合成一個不依賴於Modulerr.js –

回答

292

RequireJS 2.X現在有機地解決了非AMD模塊,如骨幹&下劃線好得多,使用新的shim配置。 (1)一個說明依賴關係(deps)(如果有的話)(可能來自paths配置,或者可能是自己有效的路徑)。(deps) (2)(可選)從要加密的文件中指定全局變量名稱,該文件應該導出到需要它的模塊函數中。 (如果你沒有指定輸出,那麼你只需要使用全局,因爲沒有東西會通過你的require/define函數。)

下面是一個簡單的示例用法shim加載Backbone。它也爲下劃線添加一個導出,儘管它沒有任何依賴關係。

require.config({ 
    shim: { 
    underscore: { 
     exports: '_' 
    }, 
    backbone: { 
     deps: ["underscore", "jquery"], 
     exports: "Backbone" 
    } 
    } 
}); 

//the "main" function to bootstrap your code 
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone) { // or, you could use these deps in a separate module using define 

}); 

注:這個簡化的代碼假定的jQuery,骨幹,並強調是在一個名爲「jquery.js和」,「Backbone.js的」和「underscore.js」在同一個目錄,因爲這檔「主要「代碼(它成爲需求的baseURL)。如果情況並非如此,則需要使用paths config

我個人認爲與內置shim功能,不使用骨幹&下劃線的分支版本的優點大於用其他流行的答案推薦AMD叉的好處,但無論哪種方式工作。

+0

此代碼是否應該與'Sample RequireJS 2.0.1 + jQuery 1.7.2項目一起使用'http://requirejs.org/docs/download.html#samplejquery? – Henry

+0

如果我正確理解你,亨利,你問是否需要爲插件填充墊片。不是,如果您使用該示例項目中的組合require-jquery.js文件。這是因爲使用組合文件時,jquery會同步加載require,所以當您嘗試在任何模塊中使用任何$插件時,jquery將保證加載。在這種情況下,當你想使用$ plugins時,你可以將它們包含在依賴列表中,就好像它們是AMD一樣,即使它們不是。這絕對是該規則的一個例外,並且通常您需要爲任何非AMD模塊提供墊片。 –

+0

請注意,填充配置與該示例項目兼容,可用於添加其他非AMD庫。 –

171

更新:自版本1.3.0起Underscore removed AMD (RequireJS) support

您可以使用amdjs/Backbone 0.9.1amdjs/Underscore 1.3.1分支,由James Burke(RequireJS的維護者)提供AMD支持。

有關更多信息AMD support for Underscore and Backbone

// main.js using RequireJS 1.0.7 
require.config({ 
    paths: { 
     'jquery': 'libs/jquery/1.7.1/jquery', 
     'underscore': 'libs/underscore/1.3.1-amdjs/underscore', // AMD support 
     'backbone': 'libs/backbone/0.9.1-amdjs/backbone', // AMD support 
     'templates': '../templates' 
    } 
}); 

require([ 
    'domReady', // optional, using RequireJS domReady plugin 
    'app' 
], function(domReady, app){ 
    domReady(function() { 
     app.initialize(); 
    }); 
}); 

的模塊正常註冊,也沒有必要爲訂單插件:

// app.js 
define([ 
    'jquery', 
    'underscore', 
    'backbone' 
], function($, _, Backbone){ 
    return { 
     initialize: function(){ 
      // you can use $, _ or Backbone here 
     } 
    }; 
}); 

下劃線實際上是可選的,因爲骨幹現在得到其對自己的依賴:

// app.js 
define(['jquery', 'backbone'], function($, Backbone){ 
    return { 
     initialize: function(){ 
      // you can use $ and Backbone here with 
      // dependencies loaded i.e. Underscore 
     } 
    }; 
}); 

有些AMD sugar你也可以這樣寫:

define(function(require) { 
    var Backbone = require('backbone'), 
     $ = require('jquery'); 

    return { 
     initialize: function(){ 
      // you can use $ and Backbone here with 
      // dependencies loaded i.e. Underscore 
     } 
    }; 
}); 

關於優化器錯誤:請仔細檢查您的構建配置。我假設你的路徑配置已關閉。如果你有一個directory setup similar to the RequireJS Docs你可以使用:

// app.build.js 
({ 
    appDir: "../", 
    baseUrl: "js", 
    dir: "../../ui-build", 
    paths: { 
     'jquery': 'libs/jquery/1.7.1/jquery', 
     'underscore': 'libs/underscore/1.3.1-amdjs/underscore', 
     'backbone': 'libs/backbone/0.9.1-amdjs/backbone', 
     'templates': '../templates' 
    }, 
    modules: [ 
     { 
      name: "main" 
     } 
    ] 
}) 
+4

這正是我一直在尋找的。謝謝!非常詳細的答案。它現在正如你所描述的那樣運行。 – Aaronius

+2

+1準確,工作和更新的答案+例子。優秀的工作Riebel,你已經幫了我,我確信其他人很多。 – Ken

+22

超級獎金保留此原始帖子後更新。 – Aaronius

3

好消息,Underscore 1.6.0現在支持requirejs define !!!

版本低於此需要的墊片,或需要underscore.js然後盲目地希望該「_」全局變量不是招;噸被瓦解(這是公平的是一個公平的賭注)

簡單地通過

加載它在
requirejs.config({ 
    paths: { 
     "underscore": "PATH/underscore-1.6.0.min", 
    } 
    }); 
4

我會直接寫下來,你可以閱讀關於requirejs.org的解釋,你可以使用下面的代碼作爲日常使用的代碼片段; (PS我使用的自耕農)(因爲很多事情更新,即時發佈此爲2014年二月的)

確保在您的index.html包含的腳本

<!-- build:js({app,.tmp}) scripts/main.js --> 
<script data-main="scripts/main" src="bower_components/requirejs/require.js"></script> 
<!-- endbuild --> 

然後,在main.js

require.config({ 
    shim: { 
     'backbone': { 
      deps: ['../bower_components/underscore/underscore.js', 'jquery'], 
      exports: 'Backbone' 
     } 
    }, 

    paths: { 
     jquery: '../bower_components/jquery/jquery', 
     backbone: '../bower_components/backbone/backbone' 
    } 
}); 

require(['views/app'], function(AppView){ 
    new AppView(); 
}); 

app.js

/** 
* App View 
*/ 
define(['backbone', 'router'], function(Backbone, MainRouter) { 
    var AppView = Backbone.View.extend({ 
     el: 'body', 

     initialize: function() { 
      App.Router = new MainRouter(); 
      Backbone.history.start(); 
     } 
    }); 

    return AppView; 
}); 

我希望我是有用的!

+1

比你知道的更有用。這正是我一直試圖建立在我的項目,bower_components和所有項目上的。謝謝@STEEL –

+0

很高興知道:) – STEEL

0
require.config({ 
    waitSeconds: 500, 
    paths: { 
    jquery: "libs/jquery/jquery", 
    jqueryCookie: "libs/jquery/jquery.cookie", 
    ..... 
    }, 

    shim: { 
    jqxcore: { 
     export: "$", 
     deps: ["jquery"] 
    }, 
    jqxbuttons: { 
     export: "$", 
     deps: ["jquery", "jqxcore"] 
    } 
    ............ 
    } 
}); 

require([ 
<i> // Load our app module and pass it to our definition function</i> 
    "app" 
], function(App) { 
    // The "app" dependency is passed in as "App" 
    // Again, the other dependencies passed in are not "AMD" therefore don't pass a parameter to this function 
    App.initialize(); 
});