[英]How do I use Backbone.js with Require.js (r.js), but resulting in 2 files after I optimize it?
我已經按照基本教程(運行r.js
后得到一個文件)
問題是,我的main.js
文件最后是500KB。 那太大了。 我想把它分成兩個文件。
我想將main.js
文件優化為兩個文件:
大多數人會點擊首頁和用戶個人資料頁面,我希望首先快速加載(同時在第二個主文件中將其他頁面加載到后台)
問題是,我不知道該怎么做。 有這樣的例子在線 ,但這些例子不使用Backbone。 他們沒有介紹如何處理路由器和app.js
我很困惑...因為我只有一個app.js
,一個router.js
...我怎么能將router.js分成兩個文件?
在處理Backbone時,我不知道如何拆分我的項目。
下面是代碼
HTML PAGE(單頁應用程序的入口點)
<html>
<head>
<script type="text/javascript" data-main='/media/js/main' src='/media/js/lib/requirejs/require-jquery.js'></script>
</head>
<body>
Hello
</body>
</html>
Main.js
require.config({
paths:{
jquery: 'lib/requirejs/require-jquery',
jquery_ui:'lib/jquery-ui/jquery-ui-1.10.3.custom',
underscore: 'lib/underscore/underscore-min',
backbone:'lib/backbone/backbone-min',
backbone_viewhelper:'lib/backbone/backbone.viewhelper',
text: 'lib/requirejs/text',
birthdaypicker: 'lib/birthdaypicker/bday-picker',
//more paths
},
waitSeconds: 30,
shim:{
'underscore':{
exports: '_'
},
'backbone':{
deps:[ 'underscore', 'jquery'],
exports: 'Backbone'
},
'backbone_viewhelper':{
deps:['underscore','backbone']
}
}
});
require([
'app',
'json2',
'jquery_ui',
'backbone_viewhelper',
'bootstrap_js',
'bootstrap_select',
'birthdaypicker',
'accounting',
'numbersonly',
'main_alert',
'string_tools',
'plupload',
//more things here
], function(App){
App.initialize();
});
App.js
define([
'jquery',
'underscore',
'backbone',
'router'
], function($, _, Backbone, Router){
var initialize = function(){
Router.initialize();
}
return {
initialize: initialize
};
});
Router.js
define([
'jquery',
'underscore',
'backbone',
'modules/index/view',
'modules/home/view',
'modules/listings_search/view',
'modules/profile/view',
//more modules
], function($, _, Backbone, indexView, homeView,searchView, profileView){
var AppRouter = Backbone.Router.extend({
initialize:function(){
_.bindAll(this);
},
routes:{
'':'index',
'home': 'home',
'register': 'register',
'login': 'login',
'listings(/start/:start)(/num/:num)': 'search',
'listings/create': 'listingsCreate',
'listings/:listing_id/edit': 'listingsEdit',
'orders/listings/:listing_id/create': 'ordersCreate',
'orders/buyer(/start/:start)(/num/:num)': 'ordersListBuyer',
'orders/seller(/start/:start)(/num/:num)': 'ordersListSeller',
'orders/:order_id': 'orders',
'orders/:order_id/messages':'messages',
'*actions': 'defaultAction'
//more stuff
},
index:function(){
app_router_view.show(indexView);
},
search:function(start, num){
var options = {
filters:{
start: start,
num: num
}
};
app_router_view.show(searchView, options);
},
static:function(template){
app_router_view.show(staticView, { static_view: { template: template }});
},
profile:function(){
app_router_view.show(profileView);
},
passResetCode:function(code){
app_router_view.show(passCodeView, {'code':code});
},
//more stuff
home:function(){
app_router_view.show(homeView);
},
defaultAction:function(actions){
this.navigate('/', { trigger:true});
}
});
var initialize = function(){
var app_router = new AppRouter;
Backbone.history.start({pushState:true, root: '/'});
$(document).on('click', 'a:not([data-bypass])', function (evt) {
var href = $(this).attr('href');
if(href){
var protocol = this.protocol + '//';
if (href.slice(protocol.length) !== protocol && href != '#') {
evt.preventDefault();
app_router.navigate(href, { trigger: true});
}
}else{
}
});
};
return {
initialize:initialize
}
});
如您所見,我的整個應用程序以main.js
,轉到app.js
,最后轉到router.js
。
我怎么能分開這個?
我已經創建了一個示例來說明如何完成它。 它包含Backbone應用程序的框架。 那里的應用程序分為:
一個main
包,它包含應用程序的核心,只呈現一個“主”視圖(在這里稱為views/app
),
以及包含所有其他視圖的secondary
包。
僅在需要時加載secondary
包。 在這個應用程序中,這意味着它應該僅在使用foo
或bar
視圖時加載,而不是之前加載。 (您可以通過檢查瀏覽器中的網絡操作來驗證這一點。)
關鍵點是:
views/app
中的視圖是應用程序的“主要”視圖。 加載它會立即實例化並呈現視圖。
js/router
模塊不直接使用其他視圖。 它調用require
首先加載視圖。 這使得foo
和bar
函數異步。
這是build.js
文件的一部分,它將應用程序分為兩個包:
modules: [ { name: "main" }, { name: "secondary", // There no module named secondary in the source, so create it. create: true, // Make sure to include all the views other than the main one. include: [ "views/foo", "views/bar" ], // Exclude everything we've included in `main`. exclude: ["main"] } ]
優化版需要像這樣的初始配置:
bundles: { "secondary": ["views/foo", "views/bar"] }
這告訴RequireJS通過加載secondary
來加載模塊views/foo
和views/bar
。
請閱讀README.md
文件以獲取更多詳細信息。
根據您共享的代碼,我創建了一個示例Web應用程序並將代碼提交到git-hub 。
申請分為2個模塊:
main
: contains modules/index/view
和modules/profile/view
other
: contains 'modules/order/view
和modules/search/view
當您請求modules/index/view
或modules/profile/view
,如果尚未下載, main.js
下載main.js
類似地,當對modules/order/view
或modules/search/view
發出請求時,如果尚未下載,則下載other.js
。 請記住使用require.js v2.1.10
或更高版本,因為它具有生成other.js
所需的包功能。
您可以通過在build.js
order, search, profile
定義為獨立模塊來進一步模塊化,以便僅在需要時下載它們。
執行構建命令的輸出:
media/js/main.js
----------------
media/js/lib/jquery/jquery-min.js
media/js/lib/underscore/underscore-min.js
media/js/lib/backbone/backbone-min.js
media/js/router.js
media/js/app.js
media/js/main.js
media/js/modules/index/model.js
media/js/modules/index/view.js
media/js/modules/profile/model.js
media/js/modules/profile/view.js
media/js/other.js
----------------
media/js/modules/order/model.js
media/js/modules/order/view.js
media/js/modules/search/model.js
media/js/modules/search/view.js
執行流程如下: index.html => media/js/main
[它有index/view, profile/view, app.js
和所有依賴項]。 默認情況下,顯示索引視圖,因為它是為主路由配置的。
單擊“配置文件”鏈接時,不再下載任何文件,因為已下載main.js
單擊“搜索/訂購”鏈接時,將下載other.js
。
在構建配置文件中,您可以指定要創建的模塊數量以及它們必須包含的依賴項(請參閱http://requirejs.org/docs/optimization.html#basics )。
你可以在https://github.com/jrburke/r.js/blob/master/build/example.build.js看到這些選項,你感興趣的部分從第350行開始。
另請參閱如何在多頁項目中使用RequireJS構建配置文件+ r.js以獲得更深入的答案
將代碼拆分為兩個文件是不可取的。
將代碼拆分為兩個文件只會增加整體加載時間,因為需要額外的包裝代碼。 此外,拆分代碼可能會不必要地增加代碼的模塊性,從而導致將來出現設計問題。
要做的就是延遲加載路由文件(這樣你首先加載首頁和用戶配置文件頁面),然后你可以在加載首頁和用戶后在后台加載其他文件個人資料頁面
可以將它拆分 - 不要誤解我的意思 - 但這樣做會產生不必要的代碼,實際上也無濟於事。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.