[Из песочницы] Кто бы смог мне подсказать, как require подключать
Одним солнечным весенним утром, мне пришла в голову замечательная идея — заняться изучением популярной библиотеки RequireJS. Я уже давно читал много хорошего и о простоте использования и о преимуществах, которые она оказывает при использовании в проектах. Поэтому и подумать не мог, что подключение RequireJS к модульному проекту на Backbone может вызвать столько проблем. Я потратил два дня на то, что должно занять не более часа. А если у разработчика нет этих двух дней? Вот и решил поделиться с другими своим опытом, чтобы сэкономить время и нервы.Немного теории (вместо предисловия)Библиотека RequireJS действительно очень проста. Доступна она, как и документация, на официальном сайте разработчика. Принцип работы библиотеки заключается в разбивании джава скрипт кода на «модули» и дальнейшее их использование. Описываются модули с помощью директивы define (), а используются — с помощью директивы require (). В чем же тогда проблема? А проблема возникла при попытке подключить к проекту другие библиотеки. Вся документация, которую я смог найти в интернете, описывала только простейшие случаи — один маленький скрипт, который использует только библиотеку jQuery, и все файлы находятся просто в одной папке. Вот и пришлось мне поломать голову, чтобы подружить между собой RequireJS, jQuery и Backbone. А теперь довольно теории, переходим к практике.Модули, модули, модули Рано или поздно, каждый разработчик приходит к пониманию необходимости разбивания большого проекта на мелкие части (модули). Займемся этим и мы. Давайте создадим простое одностраничное приложение, для наглядной демонстрации. Чтобы не изобретать велосипед, используем готовую библиотеку Backbone, которая позволяет реализовать шаблон MVC для кода на джава скрипт. Что это значит? А значит это то, что весь наш код будет разбит на вот такие модули: Контроллер (он же роутер) модель представление Кроме того, у нас будет объект Application, который отвечает за работу приложения в целом и модуль для инициализации RequireJS (он же точка входа). Для работы нам понадобятся следующие библиотеки: RequireJS Backbone underscore (без него Backbone не работает) jQuery jStorage (просто плагин для демонстрации работы зависимостей в RequireJS) json2 (нужен для jStorage) Размещаем все по своим папкам и получаем вот такую структуру:
В каждом файле у нас находится один объект. Это требование RequireJS. Если вы захотите разместить в одном файле несколько объектов — нужно будет использовать оптимизатор. Давайте превратим эти объекты в модули, т.е. подключим к RequireJS.
define (['backbone'], function (Backbone){
var Controller = Backbone.Router.extend ({ initialize: function (options) { this.appModel = options.model; },
routes: { »: «showMainPage», «result»: «showResultPage», «page/: page»: «showPage» },
showMainPage: function () { this.appModel.set ({ type: «mainpage», page: 0 }); },
showResultPage: function () { this.appModel.set ({ type: «resultpage», page: 0 }); },
showPage: function (pageNum) { this.appModel.set ({ type: «page», page: pageNum }); }, })
return Controller; }); Данный блок описывает с помощью define модуль контроллера. Define принимает три параметра:
Имя модуля (мы его опустили, потому, что использование имен для модулей требует использования оптимизатора) Зависимости (библиотеки или объекты, которые будут использоваться в коде блока) Функция (выполняется после загрузки всех зависимостей) Как видим наш модуль зависит от библиотеки Backbone, и в функцию передается переменная Backbone — переменная, которую библиотека экспортирует в глобальную область видимости приложения (как $ для jQuery). Функция обязательно должна вернуть объект, который будет доступен для использования в дальнейшем. То же самое делаем и для других модулей. define (['appModels/appModel', 'appViews/appView', 'appControllers/appController', 'jquery', 'backbone'], function (baseModel, View, Controller, $, Backbone){
var Application = (function () {
var appView;
var appTemplates = { «mainpage»: _.template ($('#main-page').html ()), «page»: _.template ($('#page').html ()), };
var appController; var appModel;
var self = null; var module = function () { self = this; }; module.prototype = { constructor: module,
init: function () {
self.initModel (); self.initView (); self.initRouter (); },
initRouter: function () {
appController = new Controller ({ model: appModel});
Backbone.history.start (); },
initView: function () {
appView = new View ({ model: appModel, templates: appTemplates, el: $(»#main-content»)});
appModel.trigger («change»); },
initModel: function () {
appModel = new baseModel (); },
};
return module; })();
return Application; }); Объект Application описывается точно так же, как контроллер. Конечно здесь больше зависимостей. И это нормально, ведь Application объединяет в одно целое контроллер, модель, представления (Views) и дает нам готовый объект, который умеет самостоятельно отслеживать изменения в приложении и эффективно реагировать (перерисовывать элементы на странице). А в функцию мы как раз и передаем все составляющие нашего приложения (объекты, которые возвращаются функцией в блоке define), плюс глобальные объекты для библиотек Backbone и jQuery. Все просто, и не понятным остается только одно — что это за пути к файлам такие 'appModels/', 'appViews/ ', 'appControllers/', почему к библиотекам мы обращаемся просто 'jquery' или 'backbone» и как Backbone работает без underscore? Поиск ответа на этот вопрос занял у меня два дня, и оказался очень простым. Не хватает конфигурации.
Конфигурация Давайте попробуем запустить наше приложение. Для этого добавим в заголовок html страницы строку
-->