Пытаюсь объединить все мои JS в один файл и нуждаюсь в некоторых советах по JS framework / типу шаблона

#javascript #jquery #design-patterns #frameworks

#javascript #jquery #шаблоны проектирования #фреймворки

Вопрос:

На всякий случай, если это имеет значение, я использую ASP.NET 3.5 с VB.NET . У меня есть вложенные мастер-страницы и панели обновлений с частичными обратными отправками. Я включаю Modernizr 1.7 с прокладкой YepNopeJs / IE в свой раздел head. Прямо перед закрывающим тегом body я включаю свой jQuery 1.6, jQuery UI 1.8.12 и это script.js Я пытаюсь собрать.

Я подумываю использовать что-то вроде:

 SITE = {

    PAGES     : { ... },
    VARS      : { ... },
    HELPERS   : { ... },
    PLUGINS   : { ... },

    init      : function() { ... }

};

SITE.init();
  

Обновить

Хорошо, следуя совету Леви, я придумал это решение:

 var SFAIC = {};                                   // Global namespace

SFAIC.common = { ... };                           // Shared properties
SFAIC.common.fn = { ... };                        // Shared functions
SFAIC.plugin = {

    qtip: $.fn.qtip,
    validate: $.fn.validate,
    validator: $.fn.validator

};
SFAIC.init = function() { ... };                  // Global initializer

$(document).ready(function() { SFAIC.init(); });
  

Тогда каждая страница имела бы свой собственный объектный литерал, подобный:

 SFAIC.Main = {};                                  // Main.aspx 

SFAIC.Main.someSection = { ... };                 // Some Section's properties
SFAIC.Main.someSection.fn = { ... };              // Some Section's functions
SFAIC.Main.anotherSection = { ... };              // Another Section's properties
SFAIC.Main.anotherSection.fn = { ... };           // Another Section's functions
SFAIC.Main.init = function() { ... };             // Main.aspx's intializer

$(document).ready(function() { SFAIC.Main.init(); });
  

Комментарии:

1. Насколько велик рассматриваемый веб-сайт? Это может иметь отношение к ответу.

2. Это своего рода вопрос с подвохом. Веб-сайт небольшой с точки зрения страниц. С точки зрения кода, он огромен. С точки зрения клиентской части, это где-то от пары сотен до тысячи строк кода на страницу. Однако я думаю, что этот объектный литерал — это тот путь, которым я ХОЧУ пойти, и, вероятно, он наиболее практичен. Я просто не знаю точно лучшего способа поместить весь код в объектный литерал и выполнить на основе страницы.

3. Обратите внимание, что в jQuery это .fn фактически означает .prototype , что это способ определения методов в объекте jQuery, а не поле для хранения функций. Это может ввести в заблуждение, если вы сравниваете его с jQuery.fn

4. Да, это меня смутило. Мне нужен был ящик для хранения моих функций. Есть ли что-то лучше или способ смешать prototype с объектными литералами?

Ответ №1:

Я рекомендую вам создать новый объект для section и новую функцию для каждой страницы / элемента.Однако, чем больше скриптов вы добавляете таким образом, тем сложнее становится управлять целым в редакторе. В Netbeans есть функция, которая позволяет вам переходить к частям объекта и помогает управлять этим.

Пример:

 var lib = {}; // your library

//maybe you like the plural name plugins better. That's fine.
lib.plugin = {
    //define plugins here
};

//maybe you like the plural name helpers better. That's fine too.
lib.helper = {
    //define your helpers here
    cycle: function() {
        //code for the cycle plug-in
    }
};

lib.account = {
    //you could stick code that is general to all account pages here
};

lib.account.overview = function() {
    //you could stick code that is specific to the account overview page here
    //maybe you'd use the cycle plug-in to show their latest posts.
    lib.plugin.cycle();

};

lib.account = {
    //you could stick code that is general to all account pages here
};

lib.account.overview = function() {
    //you could stick code that is specific to the account overview page here
    //maybe you'd use the cycle plug-in to show their latest posts.

    lib.plugin.cycle();

};
  

Затем на странице обзора учетной записи вы бы позвонили lib.account.overview() .

Комментарии:

1. Вопрос. Допустим, я использую плагин validation jQuery и плагин qtip2 jQuery. Оба подключаются к $.fn with $.extend . Следовательно, я мог бы получить к ним доступ $.fn.validate , $.fn.validator или $.fn.qtip . Было бы лучшей практикой создать, lib.plugin = { qtip: $.fn.qtip, validate: $.fn.validate, validator: $.fn.validator }; где я мог бы использовать lib.plugin.validator , lib.plugin.qtip и т.д. Или мне даже не следует беспокоиться об объекте lib.plugin и использовать $.fn маршрут?

2. Все, что можно было бы сделать с lib.* записями, это включить их для этой страницы. Вы могли бы продолжить использовать их как обычно. Кроме того, вы хотели бы использовать неуменьшенную версию скриптов в подключаемом модуле, поскольку их можно было бы еще больше сократить, включив в гигантский скрипт. Я настоятельно рекомендую, чтобы у вас был хороший редактор при использовании этого метода. Потому что это может занять довольно много времени.

3. Я использую VS2008, и вскоре мы переходим на VS2010. Я бы счел это лучшим редактором на рынке. Насколько мой plugins.js для разработки я использую неминифицированные версии всех моих плагинов. У меня есть plugins.min.js у которых есть упакованные или уменьшенные версии, которые я использую в режимах rc и production. Я предполагаю, что мой вопрос скорее предпочтительный, но было любопытно, переносят ли люди $.fn.xxx в lib.plugin.xxx для удобства чтения или они предпочитают просто использовать $.fn.xxx. Я своего рода помешанный на организационной аккуратности, когда дело доходит до моего кода. Я часто переоцениваю эти вещи, я думаю.

4. Все, на чем можно жить $.fn.method … etc не следует вызывать напрямую. вы должны вызвать $(selector).method . Вам следует избегать прямого доступа к ним или расширения их.

5. Ну, возьмем, к примеру, плагин qTip . Его значения по умолчанию находятся в $.fn.qtip.defaults , поэтому Крейг рекомендует их изменить $.fn.qtip.defaults = $.extend(true, {}, $.fn.qtip.defaults, { ... }); . Или, если у вас есть необходимость изменить свойство, которое не отображается по умолчанию, например zindex, вы должны сделать $.fn.qtip.zindex = getMaxZIndex(); . Я не хочу выполнять $("#tooltip").qtip.zindex = getMaxZIndex(); or $("#tooltip").qtip({ ... my defaults here ... }); для каждого отдельного вызова. Вот почему вы получаете доступ напрямую и устанавливаете значения по умолчанию один раз.

Ответ №2:

Для производства:

Используйте пакет типа closure, uglify или тот, который я упоминаю в конце, чтобы упаковать весь ваш код в один файл и отправить его.

Для разработки:

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

require.js .

Это означает, что у вас много модулей, и вы конкретно указываете зависимости.

Например, у вас был бы один main.js

 // main.js

require([
    "jquery.js",
    "jquery.ui.js", 
    ...
], function() {
    // if the correct location is "mysite.com/foo/" then url will be "foo"
    var url = window.location.pathname.match(//(w )//)[1] || "mainpage";
    require(url   ".js", function(pageObj) {
        // ...
    });
});

// foo.js

define({
    pageStuff: ...
});
  

Я рекомендую вам ознакомиться с документами RequireJS, чтобы понять их систему структурирования. Это одно из лучших, что я нашел.

Когда дело доходит до оптимизации всего javascript в один файл, вы просто используете их конструктор. Это должно быть частью вашей системы развертывания проекта.

Комментарии:

1. Хотя это действительно не делает того, что я хочу. У меня уже есть моя система, созданная с использованием js-файла для каждой страницы, где у меня есть возможность через ContentPlaceHolders включать js-файл этой страницы без необходимости загрузки. Если по какой-либо причине я хотел пойти по пути загрузчика, я использую Modernizr, который использует YepNopJs, так что я мог бы просто использовать это, если бы захотел. Но, поскольку я больше не хочу поддерживать все разные js-файлы, и я хочу, чтобы они все были в одном js-файле, чтобы у меня был intellisense в Visual Studio, вот почему я спрашиваю то, что я спрашиваю.

2. @Scott Один гигантский файл со всеми данными был бы для меня кошмаром. Если бы все мои методы / функции были настроены подобным образом в одном большом глобальном объекте, это привело бы к слишком большой жесткой связи.

3. @Raynos — Я просто следую совету Пола Айриша и ему подобных, в которых говорится, что нам нужно объединить js в один plugins.js файл и один script.js файл для кроссбраузерной оптимизации.

4. @Scott Я согласен с этим. Для этого вам просто нужно использовать инструмент автоматического построения, подобный тому, который я связал. Вы не записываете все это в один файл.

5. @Raynos: Я не согласен с этим методом по нескольким пунктам, но я попросил масштаб для веб-сайта, как будто он действительно большой, тогда метод, который я опубликовал, становится немного запутанным. У каждого есть свои сильные стороны и преимущества.