2015-07-16 2 views
1

Я пишу проект Backbone.js. В настоящее время, все мои приложения кода (а куча взглядов) существует в один гигантский монолитный файл структурированного так:Включая JS-файлы внутри друг друга через Grunt без Require.js

'use strict'; 
(function(window, $, Backbone){ 
    var app = app || { 
     Views: {} 
     Models: {} 
     Collections: {} 
    }; 

    app.Views.MainView = Backbone.View.extend({ 
     // etc etc. tons of code in here 
    }); 

    app.views.ChildView = Backbone.View.extend({ 
     // etc. etc. tons of code in here too. 
    }); 

    $(function() { 
     new App.Views.MainView(); 
    }); 
}(window, jQuery, Backbone)) 

Файл становится немного unweildly, и вместо этого я хотел бы вырваться из моих взглядов на их собственные файлы, то есть views/Main.js, views/Child.js.

Моя первоначальная мысль состоит в том, чтобы использовать Grunt, чтобы просто конкатенировать все файлы вместе, однако я хочу, чтобы весь код был обернут внутри IIFE, как показано выше.

Использование Grunt, какой будет самый чистый/простой способ «включить» файлы внутри этого IIFE? Что-то вроде usemin, но для внутреннего JavaScript вместо разметки.

+0

Вы не хотите, чтобы каждый файл был завернут в свое закрытие? – crush

+0

@crush нет, поскольку мне нужно, чтобы они взаимодействовали друг с другом, но я все еще довольно новичок в использовании IIFE, поэтому, если это не так, не стесняйтесь исправлять меня :) – Prefix

+0

Вы все еще можете взаимодействовать между ними, как долго поскольку материал, который вам нужен, находится на вашем объекте 'app', как определено выше. Я бы, вероятно, явно установил 'app' как часть' window', но эта глобальная переменная была бы доступна в каждом отдельном закрытии. Это также позволяет вам иметь закрытые конкретные переменные - например, переменную 'defaultOptions'. Если вы объединяете кучу модулей вместе, которые имеют 'defaultOptions', и помещают их все в одно и то же закрытие, последняя переменная' defaultOptions' будет значением, используемым всеми модулями, что, вероятно, является непреднамеренным. – crush

ответ

0

По моему опыту, я обнаружил, что лучше всего оставить свои отдельные модули внутри своих закрытий (IIFE). Следующий пример кода демонстрирует ловушкой объединения всех файлов в рамках одного закрытия, а не оборачивать каждый в своем замыкании:

//Your big closure 
 
(function() { 
 
    
 
    //Included from file 1 
 
    var defaultOptions = { 
 
     label: 'Testing1' 
 
    }; 
 
    
 
    window.MyObject1 = function (options) { 
 
     this.options = $.extend({}, defaultOptions, options); 
 
    } 
 
    
 
    //Included from file 2 
 
    var defaultOptions = { 
 
     label: 'Testing2' 
 
    }; 
 
    
 
    window.MyObject2 = function (options) { 
 
     this.options = $.extend({}, defaultOptions, options); 
 
    } 
 
    
 
})(); 
 

 
//Later in the site, you decide to use some objects: 
 
var obj1 = new MyObject1(); 
 
var obj2 = new MyObject2(); 
 

 

 
$('#obj1').text(obj1.options.label); 
 
$('#obj2').text(obj2.options.label);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<div id="obj1"></div> 
 
<div id="obj2"></div>

I обмена данными между модулями за счет использования событий.

Например, у вас есть панель инструментов и диалоговое окно, и вы хотите, чтобы диалог открывался при нажатии кнопки панели инструментов.

(function() { 
 

 
    window.MyToolbar = function() { 
 
     this.onOpenDialogButtonClicked = function() { 
 
      $(document).trigger(window.events.MyDialog.open); //you can also send it data as the second parameter if you need to. 
 
     }; 
 
    }; 
 

 
})(); 
 

 
(function (events) { 
 

 
    //Define your custom events for this dialog. 
 
    $.extend(events, { 
 
     MyDialog: { 
 
      open: 'window.events.myDialog.open' //Need a unique string here. I go back later and CRC32 these to help with minification. 
 
     } 
 
    }); 
 

 
    window.MyDialog = function() { 
 
     $(document).on(window.events.MyDialog.open, function() { 
 
      //open the dialog here! 
 
      $('#dialog').text('opened!'); 
 
     }); 
 
    }; 
 

 
})(window.events = window.events || {}); 
 

 
var toolbar = new MyToolbar(); 
 
var dialog = new MyDialog(); 
 

 
$(document).on('click', '#button', toolbar.onOpenDialogButtonClicked);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<button id="button">Open Dialog</button> 
 
<div id="dialog"></div>

Преимущество здесь в том, что нет нагрузки зависимости заказа требуется. В этом примере модуль панели инструментов требует, чтобы диалоговый модуль загружался для window.events.MyDialog.open, чтобы разрешить его, но это потребуется только при нажатии кнопки.

Если это проблема, вы можете перенести объявления событий в один файл с именем events.js или что-то в этом роде.

За исключением имени события, кнопка панели инструментов может быть нажата, и для ее открытия не требуется ссылка на диалог. Диалог прослушивает открытое событие. Если он получит один, он откроется сам. Если ни один диалог не прослушивается, кнопка просто ничего не делает.

В этом примере также показано, как модули могут связываться, присоединяя элементы к глобальному пространству, предназначенным для глобального пространства. Лично я создаю переменную «namespace», которая сидит в глобальном пространстве и присоединяет к ней все мои вещи.

Например:

(function (myNamespace) { 

    //This is assuming myNamespace.events exists already - make sure it does before calling this. 
    $.extend(myNamespace.events, { 
     MyDialog: { open: 'myNamespace.events.MyDialog.open' } 
    }); 

})(window.myNamespace = window.myNamespace || {}); 

Это просто инкапсулирует материал, который я написал, и держит его от столкновения с вещами других библиотек может разместить в глобальном пространстве.


Таким образом, в то время как вы можете сэкономить несколько байт в процессе минификации конкатенации всех файлов в одном закрытие, вы можете попасть в какие-нибудь ненужные проблемы. С включением minification и gzip несколько байтов, которые вы сохранили бы от конкатенации всего под одним закрытием, несущественны.

Я показал, как замыкания могут взаимодействовать друг с другом и скрыть элементы, которые являются частями модуля.

Я не использовал Backbone.js, поэтому извините за то, что в примерах не было никаких материалов Backbone.js. Я уверен, что идеи переводится.

Смежные вопросы