標籤:
就在前天晚上RequireJS發布了一個大版本,直接從version1.0.8升級到了2.0。隨後的幾小時James Burke又迅速的將版本調整為2.0.1,當然其配套的打包壓縮公用程式r.js也同時升級到了2.0.1。此次變化較大,代碼也進行了重構,層次更清晰可讀。功能上主要變化如下:
1,延遲模組的執行。
這是一個很大變化,以前模組載入後factory立馬執行。效能上肯定有一些損耗。2.0修改實現,再沒人詬病AMD的模組是立即執行的。現在也可以等到require的時候才執行。
2,config增加了shim,map,module,enforceDefine。
shim參數解決了使用非AMD方式定義的模組(如jQuery外掛程式)及其載入順序。使用shim參數來取代1.0版本的order外掛程式。其實在1.0版本中就曾經有人開發過use和wrap外掛程式來解決此類問題。考慮到很多開發人員有此類需求(比如某些JS模組是較早時候其他人開發的,非AMD方式)此次2.0版本直接將其內建其中。
下面是一個使用jQuery外掛程式形式配置的參數。我們知道jQuery外掛程式本質上是將命名空間掛在全域的jQuery或jQuery.fn上而非使用define定義的模組。而jQuery外掛程式都依賴於jQuery,即在require外掛程式時得保證jQuery先下載下來。可以如下配置
require.config({ shim: { ‘jquery-slide‘: [‘jquery‘] }});require([‘jquery-slide‘]);
這時會保證先下載jquery.js,然後再下載jquery-slide.js。
map參數用來解決同一個模組的不同版本問題,這一靈感來自於Dojo的packageMap。有這樣的情境:開發初期使用了的jquery-1.6.4,後期升級到了1.7.2。但擔心有些依賴jquery-1.6.4的代碼升級到1.7.2後有問題。因此保守的讓這部分代碼繼續使用1.6.4版本。這時map參數將派上用場。
假如A,B模組中使用了jquery-1.6.4.js,C,D模組中使用了jquery-1.7.2.js。如下
requirejs.config({ map: { ‘A‘: { ‘jquery‘: ‘jquery-1.6.4‘ }, ‘B‘: { ‘jquery‘: ‘jquery-1.7.2‘ } }});require([‘A‘]); // download jquery-1.6.4.jsrequire([‘B‘]); // download jquery-1.7.2.js
這時require([‘A‘])將會下載jquery-1.6.4.js,require([‘B‘])會下載jquery-1.7.2.js。模組“A”如果寫成“*”則表示除了B模組使用jquery-1.7.2之外其它模組都使用jquery-1.6.4。map參數解決了模組的各個版本問題,很好的向下相容了老代碼。
config參數用來給指定的模組傳遞一些有用的資料。如下
require.config({ config: { ‘A‘: { info: {name: ‘jack‘} } }});
使用A的模組中可以通過A.config().info擷取到該資料資訊。如
require([‘A‘], function(A) { var info = a.config().info; console.log(info);});
enforceDefine用來強制模組使用define定義,預設為false。如underscore不再支援AMD後,其代碼移除了define。此時如果仍然使用requirejs來載入它,它就是普通的js檔案了。此時如果enforceDefine設為true,雖然underscore.js能下載但requirejs會報錯。如
require.config({ enforceDefine: true});require([‘underscore‘], function(_){ console.log(_)})4,require函數增加了第三個參數errbacks。
很明顯該函數指模組檔案沒有載入成功時的回調。這個也是應一些開發人員得要求而增加,其中還包括另一個著名AMD的實現curl的作者John Hann
require([‘b‘], function(){ console.log(‘success‘);},function(err){ console.log(err)});
err會給出一些出錯提示資訊。
5,更強大的paths參數。
requirejs 1.x版本中已經有paths參數,用來映射模組別名。requirejs2.0更加強大,可以配置為一個數組,順序映射。當前面的路徑沒有成功載入時可接著使用後面的路徑。如下
requirejs.config({ enforceDefine: true, paths: { jquery: [ ‘http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min‘, ‘lib/jquery‘ ] }}); require([‘jquery‘], function ($) {});
當google cdn上的jquery.min.js沒有擷取時(假如google宕機),可以使用本地的lib/jquery.js。
6,在模組載入失敗回調中可以使用undef函數移除模組的註冊。
這個靈感來自dojo AMD loader,RequireJS取名undef。如下
require([‘jquery‘], function ($) { //Do something with $ here}, function (err) { var failedId = err.requireModules && err.requireModules[0]; if (failedId === ‘jquery‘) { requirejs.undef(failedId); }});7,刪除了jQuery domready相關代碼。
這次沒人再詬病RequireJS和jQuery耦合的太緊密。
8,刪除了priority,packagePaths,catchError.define。
這幾個參數已經有相應的替代品。
最後需要注意的是,雖然功能增加了不少。但代碼量卻減少了近60行。主要是去掉了jQuery ready相關代碼。另外newContext函數依然有1000多行。
RequireJS 2.0 正式發布