Как структурировать приложения JavaScript в разработке и производстве - PullRequest
14 голосов
/ 22 декабря 2011

Я создаю свое первое (не спагетти) большое приложение JavaScript.В то время как введение RequireJS и других структур управления зависимостями для JavaScript облегчает разделение файлов, Мне неясно, как подтолкнуть большую кодовую базу к производству .То, что я хотел бы, это способ агрегирования и минимизации / уменьшения моих скриптов Java для производства, используя что-то вроде Ready.js и UglifyJS .Или какой-то другой подход, если это имеет смысл.

Как разработчики с большими приложениями JavaScript в производстве управляют своей структурой в разработке и в производстве?

Я мог бы, дляНапример, используйте RequireJS в разработке, а затем используйте Ready / Uglify для агрегирования / минификации.Но тогда мой код был бы бессмысленным require()'s разбросанным по всему.Я уверен, что есть лучший подход.

Я также запутался, включив jQuery в эти файлы.Должен ли я обернуть каждый отдельный файл jQuery (например, представления Backbone, использующие jQuery) в отдельный отдельный $(document).ready(function(){...})?Это выглядит очень нечистым.

Ответы [ 3 ]

2 голосов
/ 22 декабря 2011

Вы можете использовать оптимизатор RequireJS .Требования не являются бессмысленными, даже в сжатом приложении, потому что вы всегда должны получить ссылку на модуль.Документы оптимизатора также говорят, что он не будет включать модуль, который был загружен с переменной, такой как

var mods = someCondition ? ['a', 'b'], ['c', 'd'];
require(mods);

Я думаю, что RequireJS должен ждать, пока DOM не будет готов и всех модулейбыли загружены, поэтому вам не нужно оборачивать каждый файл.

Тем не менее, мой любимый менеджер пакетов по-прежнему StealJS .Он может отбрасывать ненужные вызовы в производственной сборке, и модуль всегда инкапсулируется в замыкание, которое передает объект jQuery и ожидает, пока DOM не будет готов и все сценарии загружены.К сожалению, он еще не совместим со спецификациями модуля CommonJS.

1 голос
/ 22 декабря 2011

Я нашел YUI Builder хорошо работает для меня.Я не уверен, насколько это полезно, если вы не используете YUI 3, но есть большая вероятность, что вы можете адаптировать его к вашим потребностям.* RequireJS Optimizer ?

Относительно document.ready обработки;Я считаю хорошей практикой не позволять коду в модулях делать что-либо, пока они не будут инициализированы или вызваны.Таким образом, у меня будет один $(document).ready() в теге <script> внизу самой страницы, который «склеивает» модули, необходимые для этой страницы.

0 голосов
/ 09 декабря 2014

Способ борьбы со спагетти

Для эффективной разработки и простого обслуживания приложения JavaScript, в отличие от ряда специальных сценариев или непрозрачной автоматизации на низком уровне, вы можете использовать собственное приложение Qooxdoo . Невозможно описать Qooxdoo, не написав слишком много, но в случае нативного приложения (не путайте термин с C или Java, Qooxdoo - это чистый JavaScript) оно описывается следующим образом:

Для приложений, использующих пользовательские графические интерфейсы на основе HTML / CSS вместо слоя виджетов qooxdoo.

Таким образом, такое приложение не использует какие-либо слои пользовательского интерфейса Qooxdoo, а просто использует средства структуры кода и инструменты сборки. Код в Qooxdoo организован по классам, по одному на файл, как в Java. Я могу выглядеть так:

/**
 * @use(website.library.MosaicFlow)
 */
qx.Class.define('website.controller.Gallery', {

  extend : website.controller.Abstract,

  members : {

    _baseUrl : 'https://picasaweb.google.com/data/feed/api',


    _render : function(photos)
    {
      q('.preloader').remove();

      q.template.get('gallery-template', {'photos': photos}).appendTo('#gallery-container');
      var gallery = window.jQuery('#gallery-container .gallery').mosaicflow({
        'minItemWidth'    : 256,
        'itemSelector'    : '.photo',
        'autoCalculation' : false
      });
      gallery.trigger('resize');
    },

    _convert : function(item, index)
    {
      try
      {
        return {
          'url'     : item.content.src,
          'summary' : item.summary.$t,
          'thumb'   : item.media$group.media$thumbnail[0]
        };
      }
      catch(ex)
      {
        this.debug('failed to convert', index, item);
        return null;
      }
    },

    _onLoadSuccess : function(event)
    {
      var request  = event.getTarget();
      var response = request.getResponse();
      if(!qx.lang.Type.isObject(response) || !('feed' in response))
      {
        request.debug('Malformed response received');
      }
      else
      {
        this._render(response.feed.entry.map(this._convert, this).filter(function(item)
        {
          return !!item;
        }));
      }
    },

    _onLoadFail : function()
    {
      this.debug('Picasa search failed');
    },

    main : function()
    {
      var query   = /^\/gallery\/(\w+)$/.exec(window.location.pathname);
      var request = new qx.io.request.Jsonp(qx.lang.String.format('%1/all', [this._baseUrl]));
      request.setRequestData({
        'q'           : query[1],
        'thumbsize'   : 300,
        'max-results' : 20,
        'alt'         : 'json'
      });
      request.setTimeout(16000);
      request.setCache(false);
      request.addListener('fail',    this._onLoadFail,    this);
      request.addListener('success', this._onLoadSuccess, this);
      request.send();
    }

  }

});

Объектная модель Qooxdoo использует преимущества обоих миров. Он обладает качествами зрелых платформ, таких как Java, в то же время он современный и динамичный, предоставляя классы, наследование, интерфейсы, миксины, события, свойства, привязку данных и многое другое. Поскольку каждый класс имеет определенное имя и находится в дереве пространства имен, генератор Qooxdoo может воспользоваться этим. Он анализирует ваши классы и строит их синтаксические деревья. Затем он разрешает зависимости. То есть когда вы ссылаетесь на другой класс, например website.controller.Abstract. Это приводит к графу зависимостей, который используется для загрузки скриптов в правильном порядке. Обратите внимание, что все это автоматически и прозрачно для разработчика, и файлы загружаются как есть. Там нет никакой обработки, как в случае с CommonJS, нет уродливого шаблона, чтобы обернуть ваш код, как в AMD.

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

Среда разработки и производства

Вы разрабатываете сборку своего приложения (сборка необходима только тогда, когда в коде вводится новая зависимость) с так называемой исходной целью. Файлы вашего приложения загружаются в порядке зависимости, один за другим. Файлы инфраструктуры могут быть загружены один за другим, или, что лучше, встроены в несколько больших блоков. В производственной среде код вашего приложения создается с целью сборки. У вас есть возможность создать один выходной файл или создать частичную сборку, где код разбивается на большие файлы (вы можете контролировать их размер). Частичная сборка может выглядеть следующим образом (оптимизировано / распаковано):

├── [127/64kB]  website.f6ffa57fc541.js
├── [100/33kB]  website.f86294b58d1a.js
└── [361/110kB] website.js

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

http://example.com/
└── website.js
http://example.com/article
└── website.js
http://example.com/form
└── website.js
    └── website.f86294b58d1a.js
http://example.com/gallery
└── website.js
    └── website.f6ffa57fc541.js
http://example.com/geo
└── website.js

Поскольку Qooxdoo пока не нацелена на полноценные сборки веб-сайтов, а только предоставляет платформу собственного типа приложения, вам необходимо кодировать запись в приложении и некоторые основы, такие как начальная загрузка, маршрутизация URL и т. Д. Я пытался чтобы решить эту проблему с помощью qooxdoo-website-skeleton , к которым относятся приведенные выше примеры. Вы можете использовать его или написать свой собственный.

В заключение отметим, что запуск может быть не таким простым, как при использовании средней библиотеки JavaScript, но сложность пропорциональна возможной выгоде.

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