2012-12-14 54 views
19

我看到人們在require js中使用替代的定義「語法」,而不是在require js的文檔中或許多教程中描述的內容。爲什麼使用替代的requirejs define:define(function(require){...}

通常定義 「語法」

define(['module/first'], function (firstModule) { 
    //Module code with a dependency on module/first goes here. 
}); 

備用定義 「語法」

<script data-main="app/config" src="assets/js/libs/require.js"></script> 

文件:config.js:

require.config({ 
    paths: { 
     jquery:  '../assets/js/libs/jquery' 
    } 
}); 
require(['app']); 

文件:app.js:

define(function(require) { 
    var FirstModule = require('modules/first'); 
    //Module code with a dependency on module/first goes here. 

有什麼用另一種 「語法」 的優點,和缺點?

回答

40

我認爲你的解釋有點令人誤解:在這兩種情況下,你都將有一個頂級require調用,其中data-main屬性指定一個文件來啓動需要不同模塊的過程。

所以通常你都會有這個在你的HTML:

<script data-main="app/config" src="assets/js/libs/require.js"></script> 

然後,在這兩種情況下,你將有一個文件app/config這臺配置(儘管你可以在HTML做到這一點直接)並在你的模塊更重要的是呼籲require

require.config({ 
    paths: { 
    jquery:  '../assets/js/libs/jquery' 
    } 
}); 
require(['app']); 

現在,當我們去定義與這些風格不同的依賴性模塊它。在您在模塊名稱(路徑)作爲數組傳遞AMD樣式,這需要相同數量的自變量的函數:

app.js

define(['module/first', 'module/second', 'module/third'], function (firstModule, secondModule, thirdModule) { 
    // use firstModule, secondModule, thirdModule here 
}); 

在簡化的CommonJS的語法,你只是通過requiredefine,然後要求你需要什麼內嵌模塊:

app.js

define(function(require) { 
    var firstModule = require('modules/first'); 
    var secondModule = require('modules/second'); 
    var thirdModule = require('modules/third'); 
    // use firstModule, secondModule, thirdModule here 

} 

回到原來的問題,CommonJS風格相對於amd風格的優勢應該清楚。

首先,使用傳統的語法,如果需要很多模塊,它很容易錯誤地將模塊分配給錯誤的變量名稱。考慮這種常見的情況:

define(['jquery', 'underscore', 'backbone', 'modules/first', 'modules/second', 'modules/third', 'i18n', 'someOtherModule'], function ($, _, Backbone, first, second, third, I18n, someOtherModule) { 
    // ... 
}); 

向右走,你可以看到,當我們添加一個新的模塊,這個名單中,我們必須非常小心,相應的新功能的參數出現在正確的地方,否則我們可以將jQuery分配到Backbone等等。在某些情況下,這可能會創建很難追查的微妙錯誤。

現在考慮CommonJS的語法:

define(function(require) { 
    var $ = require('jquery'); 
    var _ = require('underscore'); 
    var Backbone = require('backbone'); 
    var firstModule = require('modules/first'); 
    var secondModule = require('modules/second'); 
    var thirdModule = require('modules/third'); 
    var I18n = require('i18n'); 
    var someOtherModule = require('someOtherModule'); 
    // ... 
} 

需要注意的是:

  1. 模塊的變量名稱配對是很清楚的。
  2. require語句的順序並不重要,因爲變量名是單獨配對的,而不是數組和函數之間的映射。
  3. 這些模塊不需要首先分配。它們可以在任何地方分配,只要在模塊實際使用之前。

這些只是幾個想到的原因,我敢肯定還有其他的。基本上,如果你只有一個或兩個依賴關係,任何語法都可以。但是,如果你有一個複雜的模塊依賴網絡,那麼CommonJS語法可能更可取。

注意,在RequireJS文檔,他們提到this small caveat

並非所有的瀏覽器提供一個可用的Function.prototype.toString()的結果。截至2011年10月,PS 3和更舊的Opera Mobile瀏覽器不支持。這些瀏覽器更可能需要針對網絡/設備限制優化構建模塊,因此只需使用知道如何將這些文件轉換爲標準化依賴性數組形式的優化器(如RequireJS優化器)進行構建即可。

但是,這不是一個大問題:

由於不能支持這個的toString瀏覽器的數量()掃描是非常小的,它是安全的使用所有的模塊這個加糖的形式,特別是如果您想將依賴項名稱與將保存其模塊值的變量對齊。

+0

我同意commonjs風格的優點。你是否有任何想法或想法,爲什麼amd風格在教程和requirejs文檔中受到青睞?如果結果相同,爲什麼我們不推薦每個人都使用commonjs風格? 「小警告」的唯一原因是什麼? – joholo

+1

我真的不能說,但我認爲它主要是歷史的:amd格式是標準的,而簡化的CommonJS是一個「糖」層。如果您要教RequireJS,那麼使用具有更長曆史和更廣泛採用的格式是合理的,即使「加糖」版本更簡單並且可以說更好。請注意,我大部分只是在這裏進行假設。 –

+1

我想你也可以爭辯說,通過迫使你在模塊的頂部定義所有的依賴關係(在其他任何東西之前),amd格式使得這些依賴關係更容易一目瞭然。雖然如果您使用CommonJS格式並堅持將依賴關係置於模塊的頂部,那麼這不是一個真正的問題。 –

相關問題