[英]How to structure JavaScript applications in development and production
我正在構建我的第一個(非意大利面)大型JavaScript應用程序。 雖然引入RequireJS和JavaScript的其他依賴管理框架使得分割文件更容易, 但我不清楚如何將大型代碼庫推向生產 。 我想要的是使用Ready.js和UglifyJS之類的東西來聚合和縮小/ 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.