簡體   English   中英

如何將Backbone.js與Require.js(r.js)一起使用,但在優化后會產生2個文件?

[英]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文件優化為兩個文件:

  1. 一個保存首頁和用戶個人資料頁面的頁面,因為它們訪問最多
  2. 一個包含所有其他頁面(訂購,帳戶設置,配置文件設置等)

大多數人會點擊首頁和用戶個人資料頁面,我希望首先快速加載(同時在第二個主文件中將其他頁面加載到后台)

問題是,我不知道該怎么做。 有這樣的例子在線 ,但這些例子不使用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包。 在這個應用程序中,這意味着它應該僅在使用foobar視圖時加載,而不是之前加載。 (您可以通過檢查瀏覽器中的網絡操作來驗證這一點。)

關鍵點是:

  1. views/app中的視圖是應用程序的“主要”視圖。 加載它會立即實例化並呈現視圖。

  2. js/router模塊不直接使用其他視圖。 它調用require首先加載視圖。 這使得foobar函數異步。

  3. 這是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"] } ] 
  4. 優化版需要像這樣的初始配置:

      bundles: { "secondary": ["views/foo", "views/bar"] } 

    這告訴RequireJS通過加載secondary來加載模塊views/fooviews/bar

請閱讀README.md文件以獲取更多詳細信息。

根據您共享的代碼,我創建了一個示例Web應用程序並將代碼提交到git-hub

申請分為2個模塊:

  • maincontains modules/index/viewmodules/profile/view
  • othercontains 'modules/order/viewmodules/search/view

當您請求modules/index/viewmodules/profile/view ,如果尚未下載, main.js下載main.js 類似地,當對modules/order/viewmodules/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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM