簡體   English   中英

如何在開發和生產中構建JavaScript應用程序

[英]How to structure JavaScript applications in development and production

我正在構建我的第一個(非意大利面)大型JavaScript應用程序。 雖然引入RequireJS和JavaScript的其他依賴管理框架使得分割文件更容易, 但我不清楚如何將大型代碼庫推向生產 我想要的是使用Ready.jsUglifyJS之類的東西來聚合和縮小/ uglify我的JavaScripts以進行生產。 或者其他一些方法,如果有意義的話。

生產中使用大型JavaScript應用程序的開發人員如何處理開發和生產中的結構?

例如,我可以在開發中使用RequireJS,然后使用Ready / Uglify進行聚合/縮小。 但是那時候我的代碼會有無意義的require()'s分散在各處。 我相信有更好的方法。

我也很困惑在這些文件中包含jQuery。 我應該在他們自己獨立的$(document).ready(function(){...})包裝每個單獨的jQuery文件(例如使用jQuery的Backbone視圖$(document).ready(function(){...})嗎? 這看起來非常糟糕。

您可以使用RequireJS優化器 即使在壓縮的應用程序中,這些要求也毫無意義,因為您始終必須獲得對模塊的引用。 優化器文檔還說,它不會包含已加載變量的模塊

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

我認為RequireJS應該等到DOM准備好並且所有模塊都已加載,因此您不需要包裝每個文件。

也就是說,我最喜歡的包經理仍然是StealJS 它可以在生產構建中啟動不必要的調用,並且模塊總是封裝在一個閉包中,該閉包將傳遞jQuery對象並等待直到DOM准備好並且所有腳本都已加載。 不幸的是,它還沒有與CommonJS模塊規范兼容。

我發現YUI Builder對我很有用。 如果你不使用YUI 3,我不確定它是多么有用,但你很有可能根據你的需要調整它。

另一方面,你看過RequireJS Optimizer了嗎?

關於document.ready處理; 我認為最好不要讓模塊中的代碼在初始化或調用之前做任何事情。 所以我會在頁面底部的<script>標簽中有一個$(document).ready() ,它將該頁面上所需的模塊“粘合在一起”。

反意粉的方式

為了有效地開發和輕松維護JavaScript應用程序,而不是許多臨時腳本或subpar非透明自動化,您可以使用本機Qooxdoo應用程序 如果不寫太多,就不可能覆蓋Qooxdoo,但是對於本機應用程序(不要將術語與C或Java混淆,Qooxdoo是純JavaScript),它被描述為:

對於使用基於HTML / CSS的自定義GUI而不是qooxdoo的小部件層的應用程序。

因此,此類應用程序不使用任何Qooxdoo UI層,而只使用代碼結構工具和構建工具。 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庫。 您可以只需要為庫編寫一個虛擬包裝器,以便在構建過程中包含它。

開發和生產環境

您開發構建應用程序(僅在代碼中引入新依賴項時才需要構建),並使用所謂的源目標。 您的應用程序文件按依賴順序逐個加載。 框架文件可以逐個加載,或者哪個是更好的選項,它們構建在幾個大塊中。 在生產環境中,您的應用程序代碼使用構建目標構建。 您可以選擇生成單個輸出文件,或者具有部分生成,其中代碼在大文件中分塊(您可以控制它們的大小)。 部分構建可能看起來像這樣(優化/ gzipped):

├── [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庫那樣容易啟動,但復雜性與最終的好處成正比。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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