免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

RequireJs如何使用

這篇文章主要為大家展示了“RequireJs如何使用”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“RequireJs如何使用”這篇文章吧。

創(chuàng)新互聯(lián)公司主要從事成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)芙蓉,十多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):028-86922220

§ 1.使用

§ 1.1 加載 JavaScript 文件

RequireJS的目標(biāo)是鼓勵(lì)代碼的模塊化,它使用了不同于傳統(tǒng)<script>標(biāo)簽的腳本加載步驟。可以用它來(lái)加速、優(yōu)化代碼,但其主要目的還是為了代碼的模塊化。

RequireJS以一個(gè)相對(duì)于baseUrl的地址來(lái)加載所有的代碼。 頁(yè)面頂層<script>標(biāo)簽含有一個(gè)特殊的屬性data-main,require.js使用它來(lái)啟動(dòng)腳本加載過(guò)程,而baseUrl一般設(shè)置到與該屬性相一致的目錄。

baseUrl亦可通過(guò)RequireJS config手動(dòng)設(shè)置。如果沒(méi)有顯式指定config及data-main,則默認(rèn)的baseUrl為包含RequireJS的那個(gè)HTML頁(yè)面的所屬目錄。

RequireJS默認(rèn)假定所有的依賴(lài)資源都是js腳本,因此無(wú)需在module ID上再加".js"后綴,RequireJS在進(jìn)行module ID到path的解析時(shí)會(huì)自動(dòng)補(bǔ)上后綴。你可以通過(guò)paths config設(shè)置一組腳本,這些有助于我們?cè)谑褂媚_本時(shí)碼更少的字。

有時(shí)候你想避開(kāi)"baseUrl + paths"的解析過(guò)程,而是直接指定加載某一個(gè)目錄下的腳本。此時(shí)可以這樣做:如果一個(gè)module ID符合下述規(guī)則之一,其ID解析會(huì)避開(kāi)常規(guī)的"baseUrl + paths"配置,而是直接將其加載為一個(gè)相對(duì)于當(dāng)前HTML文檔的腳本:

以 ".js" 結(jié)束.
以 "/" 開(kāi)始.
包含 URL 協(xié)議, 如 "http:" or "https:".

一般來(lái)說(shuō),最好還是使用baseUrl及"paths" config去設(shè)置module ID。它會(huì)給你帶來(lái)額外的靈活性,如便于腳本的重命名、重定位等。 同時(shí),為了避免凌亂的配置,最好不要使用多級(jí)嵌套的目錄層次來(lái)組織代碼,而是要么將所有的腳本都放置到baseUrl中,要么分置為項(xiàng)目庫(kù)/第三方庫(kù)的一個(gè)扁平結(jié)構(gòu),如下:

www/
index.html
js/
app/
sub.js
lib/
jquery.js
canvas.js
app.js

index.html:

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

app.js:

requirejs.config({
  //By default load any module IDs from js/lib
  baseUrl: 'js/lib',
  //except, if the module ID starts with "app",
  //load it from the js/app directory. paths
  //config is relative to the baseUrl, and
  //never includes a ".js" extension since
  //the paths config could be for a directory.
  paths: {
    app: '../app'
  }
});
//Start the main app logic.
requirejs(['jquery', 'canvas', 'app/sub'],
function  ($, canvas, sub) {
  //jQuery, canvas and the app/sub module are all
  //loaded and can be used here now.
});

注意在示例中,三方庫(kù)如jQuery沒(méi)有將版本號(hào)包含在他們的文件名中。我們建議將版本信息放置在單獨(dú)的文件中來(lái)進(jìn)行跟蹤。使用諸如volo這類(lèi)的工具,可以將package.json打上版本信息,并在磁盤(pán)上保持文件名為"jquery.js"。這有助于你保持配置的最小化,避免為每個(gè)庫(kù)版本設(shè)置一條path。例如,將"jquery"配置為"jquery-1.7.2"。

理想狀況下,每個(gè)加載的腳本都是通過(guò)define()來(lái)定義的一個(gè)模塊;但有些"瀏覽器全局變量注入"型的傳統(tǒng)/遺留庫(kù)并沒(méi)有使用define()來(lái)定義它們的依賴(lài)關(guān)系,你必須為此使用shim config來(lái)指明它們的依賴(lài)關(guān)系。 如果你沒(méi)有指明依賴(lài)關(guān)系,加載可能報(bào)錯(cuò)。這是因?yàn)榛谒俣鹊脑?,RequireJS會(huì)異步地以無(wú)序的形式加載這些庫(kù)。

§ 1.2 data-main 入口點(diǎn)

require.js 在加載的時(shí)候會(huì)檢察data-main 屬性:

<script data-main="scripts/main" src="scripts/require.js"></script>

你可以在data-main指向的腳本中設(shè)置模板加載 選項(xiàng),然后加載第一個(gè)應(yīng)用模塊。.注意:你在main.js中所設(shè)置的腳本是異步加載的。所以如果你在頁(yè)面中配置了其它JS加載,則不能保證它們所依賴(lài)的JS已經(jīng)加載成功。例如:

<script data-main="scripts/main" src="scripts/require.js"></script>
<script src="scripts/other.js"></script>
// contents of main.js:
require.config({
  paths: {
    foo: 'libs/foo-1.1.3'
  }
});
// contents of other.js:
// This code might be called before the require.config() in main.js has executed. 
// When that happens, require.js will attempt to load 'scripts/foo.js' instead of 'scripts/libs/foo-1.1.3.js'
require( ['foo'], function( foo ) {
});

§ 1.3 定義模塊

模塊不同于傳統(tǒng)的腳本文件,它良好地定義了一個(gè)作用域來(lái)避免全局名稱(chēng)空間污染。它可以顯式地列出其依賴(lài)關(guān)系,并以函數(shù)(定義此模塊的那個(gè)函數(shù))參數(shù)的形式將這些依賴(lài)進(jìn)行注入,而無(wú)需引用全局變量。RequireJS的模塊是模塊模式的一個(gè)擴(kuò)展,其好處是無(wú)需全局地引用其他模塊。

RequireJS的模塊語(yǔ)法允許它盡快地加載多個(gè)模塊,雖然加載的順序不定,但依賴(lài)的順序最終是正確的。同時(shí)因?yàn)闊o(wú)需創(chuàng)建全局變量,甚至可以做到在同一個(gè)頁(yè)面上同時(shí)加載同一模塊的不同版本。

一個(gè)磁盤(pán)文件應(yīng)該只定義 1 個(gè)模塊。多個(gè)模塊可以使用內(nèi)置優(yōu)化工具將其組織打包。

§ 1.3.1 簡(jiǎn)單的值對(duì)

如果一個(gè)模塊僅含值對(duì),沒(méi)有任何依賴(lài),則在define()中定義這些值對(duì)就好了:

//Inside file my/shirt.js:
define({
  color: "black",
  size: "unisize"
});

§ 1.3.2 函數(shù)式定義

如果一個(gè)模塊沒(méi)有任何依賴(lài),但需要一個(gè)做setup工作的函數(shù),則在define()中定義該函數(shù),并將其傳給define():

//my/shirt.js now does setup work
//before returning its module definition.
define(function () {
  //Do setup work here
  return {
    color: "black",
    size: "unisize"
  }
});

§ 1.3.3 存在依賴(lài)的函數(shù)式定義

如果模塊存在依賴(lài):則第一個(gè)參數(shù)是依賴(lài)的名稱(chēng)數(shù)組;第二個(gè)參數(shù)是函數(shù),在模塊的所有依賴(lài)加載完畢后,該函數(shù)會(huì)被調(diào)用來(lái)定義該模塊,因此該模塊應(yīng)該返回一個(gè)定義了本模塊的object。依賴(lài)關(guān)系會(huì)以參數(shù)的形式注入到該函數(shù)上,參數(shù)列表與依賴(lài)名稱(chēng)列表一一對(duì)應(yīng)。

//my/shirt.js now has some dependencies, a cart and inventory module in the same directory as shirt.js
define(["./cart", "./inventory"], function(cart, inventory) {
    //return an object to define the "my/shirt" module.
    return {
      color: "blue",
      size: "large",
      addToCart: function() {
        inventory.decrement(this);
        cart.add(this);
      }
    }
  }
);

本示例創(chuàng)建了一個(gè)my/shirt模塊,它依賴(lài)于my/cart及my/inventory。磁盤(pán)上各文件分布如下:

my/cart.js
my/inventory.js
my/shirt.js

模塊函數(shù)以參數(shù)"cart"及"inventory"使用這兩個(gè)以"./cart"及"./inventory"名稱(chēng)指定的模塊。在這兩個(gè)模塊加載完畢之前,模塊函數(shù)不會(huì)被調(diào)用。

嚴(yán)重不鼓勵(lì)模塊定義全局變量。遵循此處的定義模式,可以使得同一模塊的不同版本并存于同一個(gè)頁(yè)面上(參見(jiàn) 高級(jí)用法 )。另外,函參的順序應(yīng)與依賴(lài)順序保存一致。

返回的object定義了"my/shirt"模塊。這種定義模式下,"my/shirt"不作為一個(gè)全局變量而存在。

§ 1.3.4 將模塊定義為一個(gè)函數(shù)

對(duì)模塊的返回值類(lèi)型并沒(méi)有強(qiáng)制為一定是個(gè)object,任何函數(shù)的返回值都是允許的。此處是一個(gè)返回了函數(shù)的模塊定義:

//A module definition inside foo/title.js. It uses my/cart and my/inventory modules from before,
//but since foo/title.js is in a different directory than the "my" modules, it uses the "my" in the module dependency name to find them. 
//The "my" part of the name can be mapped to any directory, but by default, it is assumed to be a sibling to the "foo" directory.
define(["my/cart", "my/inventory"],function(cart, inventory) {
  //return a function to define "foo/title".
  //It gets or sets the window title.
  return function(title) {
    return title ? (window.title = title) :
        inventory.storeName + ' ' + cart.name;
  }
});

§ 1.3.5 簡(jiǎn)單包裝CommonJS來(lái)定義模塊

如果你現(xiàn)有一些以CommonJS模塊格式編寫(xiě)的代碼,而這些代碼難于使用上述依賴(lài)名稱(chēng)數(shù)組參數(shù)的形式來(lái)重構(gòu),你可以考慮直接將這些依賴(lài)對(duì)應(yīng)到一些本地變量中進(jìn)行使用。你可以使用一個(gè)CommonJS的簡(jiǎn)單包裝來(lái)實(shí)現(xiàn):

define(function(require, exports, module) {
    var a = require('a'),
      b = require('b');
    //Return the module value
    return function () {};
  }
);

該包裝方法依靠Function.prototype.toString()將函數(shù)內(nèi)容賦予一個(gè)有意義的字串值,但在一些設(shè)備如PS3及一些老的Opera手機(jī)瀏覽器中不起作用??紤]在這些設(shè)備上使用優(yōu)化器將依賴(lài)導(dǎo)出為數(shù)組形式。

§ 1.3.6 定義一個(gè)命名模塊

你可能會(huì)看到一些define()中包含了一個(gè)模塊名稱(chēng)作為首個(gè)參數(shù):

//Explicitly defines the "foo/title" module:
define("foo/title",["my/cart", "my/inventory"],function(cart, inventory) {
    //Define foo/title object in here.
  }
);

這些常由優(yōu)化工具生成。你也可以自己顯式指定模塊名稱(chēng),但這使模塊更不具備移植性——就是說(shuō)若你將文件移動(dòng)到其他目錄下,你就得重命名。一般最好避免對(duì)模塊硬編碼,而是交給優(yōu)化工具去生成。優(yōu)化工具需要生成模塊名以將多個(gè)模塊打成一個(gè)包,加快到瀏覽器的載人速度。

§ 1.3.7 其他注意事項(xiàng)

一個(gè)文件一個(gè)模塊: 每個(gè)Javascript文件應(yīng)該只定義一個(gè)模塊,這是模塊名-至-文件名查找機(jī)制的自然要求。多個(gè)模塊會(huì)被優(yōu)化工具組織優(yōu)化,但你在使用優(yōu)化工具時(shí)應(yīng)將多個(gè)模塊放置到一個(gè)文件中。

define()中的相對(duì)模塊名: 為了可以在define()內(nèi)部使用諸如require("./relative/name")的調(diào)用以正確解析相對(duì)名稱(chēng),記得將"require"本身作為一個(gè)依賴(lài)注入到模塊中:

define(["require", "./relative/name"], function(require) {
  var mod = require("./relative/name");
});

或者更好地,使用下述為轉(zhuǎn)換CommonJS模塊所設(shè)的更短的語(yǔ)法:

define(function(require) {
  var mod = require("./relative/name");
});

相對(duì)路徑在一些場(chǎng)景下格外有用,例如:為了以便于將代碼共享給其他人或項(xiàng)目,你在某個(gè)目錄下創(chuàng)建了一些模塊。你可以訪(fǎng)問(wèn)模塊的相鄰模塊,無(wú)需知道該目錄的名稱(chēng)。

生成相對(duì)于模塊的URL地址: 你可能需要生成一個(gè)相對(duì)于模塊的URL地址。你可以將"require"作為一個(gè)依賴(lài)注入進(jìn)來(lái),然后調(diào)用require.toUrl()以生成該URL:

define(["require"], function(require) {
  var cssUrl = require.toUrl("./style.css");
});

控制臺(tái)調(diào)試:如果你需要處理一個(gè)已通過(guò)require(["module/name"], function(){})調(diào)用加載了的模塊,可以使用模塊名作為字符串參數(shù)的require()調(diào)用來(lái)獲取它:

require("module/name").callSomeFunction()

注意這種形式僅在"module/name"已經(jīng)由其異步形式的require(["module/name"])加載了后才有效。只能在define內(nèi)部使用形如"./module/name"的相對(duì)路徑。

§ 1.3.8 循環(huán)依賴(lài)

如果你定義了一個(gè)循環(huán)依賴(lài)(a依賴(lài)b,b同時(shí)依賴(lài)a),則在這種情形下當(dāng)b的模塊函數(shù)被調(diào)用的時(shí)候,它會(huì)得到一個(gè)undefined的a。b可以在模塊已經(jīng)定義好后用require()方法再獲取(記得將require作為依賴(lài)注入進(jìn)來(lái)):

//Inside b.js:
define(["require", "a"],
  function(require, a) {
    //"a" in this case will be null if a also asked for b,
    //a circular dependency.
    return function(title) {
      return require("a").doSomething();
    }
  }
);

一般說(shuō)來(lái)你無(wú)需使用require()去獲取一個(gè)模塊,而是應(yīng)當(dāng)使用注入到模塊函數(shù)參數(shù)中的依賴(lài)。循環(huán)依賴(lài)比較罕見(jiàn),它也是一個(gè)重構(gòu)代碼重新設(shè)計(jì)的警示燈。但不管怎樣,有時(shí)候還是要用到循環(huán)依賴(lài),這種情形下就使用上述的require()方式來(lái)解決。

如果你熟悉CommonJS,你可以考慮使用exports為模塊建立一個(gè)空object,該object可以立即被其他模塊引用。在循環(huán)依賴(lài)的兩頭都如此操作之后,你就可以安全地持有其他模塊了。這種方法僅在每個(gè)模塊都是輸出object作為模塊值的時(shí)候有效,換成函數(shù)無(wú)效。

//Inside b.js:
define(function(require, exports, module) {
  //If "a" has used exports, then we have a real object reference here.
  //However, we cannot useany of a's properties until after b returns a value.
  var a = require("a");
  exports.foo = function () {
    return a.bar();
  };
});

或者,如果你使用依賴(lài)注入數(shù)組的步驟,則可用注入特殊的"exports"來(lái)解決:

//Inside b.js:
define(['a', 'exports'], function(a, exports) {
  //If "a" has used exports, then we have a real object reference here.
  //However, we cannot useany of a's properties until after b returns a value.
  exports.foo = function () {
    return a.bar();
  };
});

§ 1.3.9 JSONP服務(wù)依賴(lài)

JSONP是在javascript中服務(wù)調(diào)用的一種方式。它僅需簡(jiǎn)單地通過(guò)一個(gè)script標(biāo)簽發(fā)起HTTP GET請(qǐng)求,是實(shí)現(xiàn)跨域服務(wù)調(diào)用一種公認(rèn)手段。

為了在RequireJS中使用JSON服務(wù),須要將callback參數(shù)的值指定為"define"。這意味著你可將獲取到的JSONP URL的值看成是一個(gè)模塊定義。

下面是一個(gè)調(diào)用JSONP API端點(diǎn)的示例。該示例中,JSONP的callback參數(shù)為"callback",因此"callback=define"告訴API將JSON響應(yīng)包裹到一個(gè)"define()"中:

require(["http://example.com/api/data.json?callback=define"],  
  function (data) {
    //The data object will be the API response for theJSONP data call.
    console.log(data);
  }
);

僅支持返回值類(lèi)型為JSON object的JSONP服務(wù),其他返回類(lèi)型如數(shù)組、字串、數(shù)字等都不能支持。

§ 2.機(jī)制

RequireJS使用head.appendChild()將每一個(gè)依賴(lài)加載為一個(gè)script標(biāo)簽。

RequireJS等待所有的依賴(lài)加載完畢,計(jì)算出模塊定義函數(shù)正確調(diào)用順序,然后依次調(diào)用它們。

在同步加載的服務(wù)端JavaScript環(huán)境中,可簡(jiǎn)單地重定義require.load()來(lái)使用RequireJS。build系統(tǒng)就是這么做的。該環(huán)境中的require.load實(shí)現(xiàn)可在build/jslib/requirePatch.js中找到。

未來(lái)可能將該部分代碼置入require/目錄下作為一個(gè)可選模塊,這樣你可以在你的宿主環(huán)境中使用它來(lái)獲得正確的加載順序。

§ 3.配置選配

當(dāng)在頂層HTML頁(yè)面(或不作為一個(gè)模塊定義的頂層腳本文件)中,可將配置作為首項(xiàng)放入:

<script src="scripts/require.js"></script>
<script>
 require.config({
  baseUrl: "/another/path",
  paths: {
    "some": "some/v1.0"
  },
  waitSeconds: 15
 });
 require( ["some/module", "my/module", "a.js", "b.js"],
  function(someModule,  myModule) {
    //This function will be called when all the dependencies
    //listed above are loaded. Note that this function could
    //be called before the page is loaded.
    //This callback is optional.
  }
 );
</script>
<script>
  var require = {
    deps: ["some/module1", "my/module2", "a.js", "b.js"],
    callback: function(module1, module2) {
      //This function will be called when all the dependencies
      //listed above in deps are loaded. Note that this
      //function could be called before the page is loaded.
      //This callback is optional.
    }
  };
</script>
<script src="scripts/require.js"></script>

或者,你將配置作為全局變量"require"在require.js加載之前進(jìn)行定義,它會(huì)被自動(dòng)應(yīng)用。下面的示例定義的依賴(lài)會(huì)在require.js一旦定義了require()之后即被加載:

requirejs.config({
  bundles: {
    'primary': ['main', 'util', 'text', 'text!template.html'],
    'secondary': ['text!secondary.html']
  }
});
require(['util', 'text'], function(util, text) {
  //The script for module ID 'primary' was loaded,
  //and that script included the define()'d
  //modules for 'util' and 'text'
});

注意: 最好使用 var require = {} 的形式而不是 window.require = {}的形式。后者在IE中運(yùn)行不正常。

支持的配置項(xiàng):

baseUrl :所有模塊的查找根路徑。所以上面的示例中,"my/module"的標(biāo)簽src值是"/another/path/my/module.js"。當(dāng)加載純.js文件(依賴(lài)字串以/開(kāi)頭,或者以.js結(jié)尾,或者含有協(xié)議),不會(huì)使用baseUrl。因此a.js及b.js都在包含上述代碼段的HTML頁(yè)面的同目錄下加載。

如未顯式設(shè)置baseUrl,則默認(rèn)值是加載require.js的HTML所處的位置。如果用了data-main屬性,則該路徑就變成baseUrl。

paths :path映射那些不直接放置于baseUrl下的模塊名。設(shè)置path時(shí)起始位置是相對(duì)于baseUrl的,除非該path設(shè)置以"/"開(kāi)頭或含有URL協(xié)議(如http:)。在上述的配置下,"some/module"的script標(biāo)簽src值是"/another/path/some/v1.0/module.js"。

用于模塊名的path不應(yīng)含有.js后綴,因?yàn)橐粋€(gè)path有可能映射到一個(gè)目錄。路徑解析機(jī)制會(huì)自動(dòng)在映射模塊名到path時(shí)添加上.js后綴。在文本模版之類(lèi)的場(chǎng)景中使用require.toUrl()時(shí)它也會(huì)添加合適的后綴。

在瀏覽器中運(yùn)行時(shí),可指定路徑的備選(fallbacks),以實(shí)現(xiàn)諸如首先指定了從cdn中加載,一旦CDN加載失敗則從本地位置中加載這類(lèi)的機(jī)制。

shim: 為那些沒(méi)有使用define()來(lái)聲明依賴(lài)關(guān)系、設(shè)置模塊的"瀏覽器全局變量注入"型腳本做依賴(lài)和導(dǎo)出配置。

下面有個(gè)示例,它需要 RequireJS 2.1.0+,并且假定backbone.js、underscore.js 、jquery.js都裝于baseUrl目錄下。如果沒(méi)有,則你可能需要為它們?cè)O(shè)置paths config:

requirejs.config({
  //Remember: only use shim config for non-AMD scripts,scripts that do not already call define().
  //The shimconfig will not work correctly if used on AMD scripts,
  //in particular, the exports and init config will notbe triggered, and the deps config will be confusingfor those cases.
  shim: {
    'backbone': {
      //These script dependencies should be loaded before loadingbackbone.js|譯|在加載backbone.js之前應(yīng)先加載它的依賴(lài)函數(shù)underscore.js和jquery.js
      deps: ['underscore', 'jquery'],
      //Once loaded, use the global 'Backbone' as themodule value.|譯|加載完畢后該模塊使用的引用名
      exports: 'Backbone'
    },
    'underscore': {
      exports: '_'
    },
    'foo': {
      deps: ['bar'],
      exports: 'Foo',
      init: function (bar) {
        //Using a function allows you to call noConflict forlibraries that support it, and do other cleanup.
        //However, plugins for those libraries may still want a global.
        //"this" for the function will be the global object.
        //The dependencies will be passed in as function arguments.
        //If this function returns a value,then that value is used as the module export valueinstead of the object found via the 'exports' string.
        //Note: jQuery registers as an AMD module via define(),so this will not work for jQuery.
        //See notes sectionbelow for an approach for jQuery.
        return this.Foo.noConflict();
      }
    }
  }
});
//Then, later in a separate file, call it 'MyModel.js', a module is defined,specifting 'backbone' as a dependency.
//RequireJS will use the shim config to properly load 'backbone' and give a local reference to this module.
//The global Backbone will still exist on the page too.
define(['backbone'], function (Backbone) {
 return Backbone.Model.extend({});
});

 RequireJS 2.0.*中,shim配置中的"exports"屬性可以是一個(gè)函數(shù)而不是字串。這種情況下它就起到上述示例中的"init"屬性的功能。 RequireJS 2.1.0+中加入了"init"承接庫(kù)加載后的初始工作,以使exports作為字串值被enforceDefine所使用。

那些僅作為jQuery或Backbone的插件存在而不導(dǎo)出任何模塊變量的"模塊"們,shim配置可簡(jiǎn)單設(shè)置為依賴(lài)數(shù)組:

requirejs.config({
  shim: {
    'jquery.colorize': ['jquery'],
    'jquery.scroll': ['jquery'],
    'backbone.layoutmanager': ['backbone']
  }
});

但請(qǐng)注意,若你想在IE中使用404加載檢測(cè)以啟用path備選(fallbacks)或備錯(cuò)(errbacks),則需要給定一個(gè)字串值的exports以使loader能夠檢查出腳本是否實(shí)際加載了(init中的返回值不會(huì)用于enforceDefine檢查中):

requirejs.config({
  shim: {
    'jquery.colorize': {
      deps: ['jquery'],
      exports: 'jQuery.fn.colorize'
    },
    'jquery.scroll': {
      deps: ['jquery'],
      exports: 'jQuery.fn.scroll'
    },
    'backbone.layoutmanager': {
      deps: ['backbone']
      exports: 'Backbone.LayoutManager'
    }
  }
});

"shim"配置的重要注意事項(xiàng):

shim配置僅設(shè)置了代碼的依賴(lài)關(guān)系,想要實(shí)際加載shim指定的或涉及的模塊,仍然需要一個(gè)常規(guī)的require/define調(diào)用。設(shè)置shim本身不會(huì)觸發(fā)代碼的加載。

請(qǐng)僅使用其他"shim"模塊作為shim腳本的依賴(lài),或那些沒(méi)有依賴(lài)關(guān)系,并且在調(diào)用define()之前定義了全局變量(如jQuery或lodash)的AMD庫(kù)。否則,如果你使用了一個(gè)AMD模塊作為一個(gè)shim配置模塊的依賴(lài),在build之后,AMD模塊可能在shim托管代碼執(zhí)行之前都不會(huì)被執(zhí)行,這會(huì)導(dǎo)致錯(cuò)誤。終極的解決方案是將所有shim托管代碼都升級(jí)為含有可選的AMD define()調(diào)用。(這一塊不明白~~?。。。?/p>

"shim"配置的優(yōu)化器重要注意事項(xiàng):

您應(yīng)當(dāng)使用 mainConfigFile build配置項(xiàng)來(lái)指定含有shim配置的文件位置,否則優(yōu)化器不會(huì)知曉shim配置。另一個(gè)手段是將shim配置復(fù)制到build profile中。(這一塊不明白~~?。。。?/p>

不要在一個(gè)build中混用CDN加載和shim配置。示例場(chǎng)景,如:你從CDN加載jQuery的同時(shí)使用shim配置加載依賴(lài)于jQuery的原版Backbone。不要這么做。您應(yīng)該在build中將jQuery內(nèi)聯(lián)而不是從CDN加載,否則build中內(nèi)聯(lián)的Backbone會(huì)在CDN加載jQuery之前運(yùn)行。這是因?yàn)閟him配置僅延時(shí)加載到所有的依賴(lài)已加載,而不會(huì)做任何define的自動(dòng)裝裹(auto-wrapping)。在build之后,所有依賴(lài)都已內(nèi)聯(lián),shim配置不能延時(shí)執(zhí)行非define()的代碼。define()的模塊可以在build之后與CDN加載代碼一并工作,因?yàn)樗鼈円褜⒆约旱拇a合理地用define裝裹了,在所有的依賴(lài)都已加載之前不會(huì)執(zhí)行。因此記?。簊him配置僅是個(gè)處理非模塊(non-modular)代碼、遺留代碼的將就手段,如可以應(yīng)盡量使用define()的模塊。

對(duì)于本地的多文件build,上述的CDN加載建議仍然適用。任何shim過(guò)的腳本,它們的依賴(lài)必須加載于該腳本執(zhí)行之前。這意味著要么直接在含有shim腳本的build層build它的依賴(lài),要么先使用require([], function (){})調(diào)用來(lái)加載它的依賴(lài),然后對(duì)含有shim腳本的build層發(fā)出一個(gè)嵌套的require([])調(diào)用。

如果您使用了uglifyjs來(lái)壓縮代碼,不要將uglify的toplevel選項(xiàng)置為true,或在命令行中不要使用 -mt。 該選項(xiàng)會(huì)破壞shim用于找到exports的全局名稱(chēng)。

map: 對(duì)于給定的模塊前綴,使用一個(gè)不同的模塊ID來(lái)加載該模塊。

該手段對(duì)于某些大型項(xiàng)目很重要:如有兩類(lèi)模塊需要使用不同版本的"foo",但它們之間仍需要一定的協(xié)同。 在那些基于上下文的多版本實(shí)現(xiàn)中很難做到這一點(diǎn)。而且,paths配置僅用于為模塊ID設(shè)置root paths,而不是為了將一個(gè)模塊ID映射到另一個(gè)。map示例:

requirejs.config({
  map: {
    'some/newmodule': {
      'foo': 'foo1.2'
    },
    'some/oldmodule': {
      'foo': 'foo1.0'
    }
  }
});

如果各模塊在磁盤(pán)上分布如下:

foo1.0.js
foo1.2.js
some/
newmodule.js
oldmodule.js

當(dāng)“some/newmodule”調(diào)用了“require('foo')”,它將獲取到foo1.2.js文件;而當(dāng)“some/oldmodule”調(diào)用“`require('foo')”時(shí)它將獲取到foo1.0.js。

該特性?xún)H適用于那些調(diào)用了define()并將其注冊(cè)為匿名模塊的真正AMD模塊腳本。并且,請(qǐng)?jiān)趍ap配置中僅使用絕對(duì)模塊ID,“../some/thing”之類(lèi)的相對(duì)ID不能工作。

另外在map中支持“*”,意思是“對(duì)于所有的模塊加載,使用本map配置”。如果還有更細(xì)化的map配置,會(huì)優(yōu)先于“*”配置。示例:

requirejs.config({
  map: {
    '*': {
      'foo': 'foo1.2'
    },
    'some/oldmodule': {
      'foo': 'foo1.0'
    }
  }
});

意思是除了“some/oldmodule”外的所有模塊,當(dāng)要用“foo”時(shí),使用“foo1.2”來(lái)替代。對(duì)于“some/oldmodule”自己,則使用“foo1.0”。

config:常常需要將配置信息傳給一個(gè)模塊。這些配置往往是application級(jí)別的信息,需要一個(gè)手段將它們向下傳遞給模塊。在RequireJS中,基于requirejs.config()的config配置項(xiàng)來(lái)實(shí)現(xiàn)。要獲取這些信息的模塊可以加載特殊的依賴(lài)“module”,并調(diào)用module.config()。示例:

requirejs.config({
  config: {
    'bar': {
      size: 'large'
    },
    'baz': {
      color: 'blue'
    }
  }
});
//bar.js, which uses simplified CJS wrapping:
//http://requirejs.org/docs/whyamd.html#sugar
define(function (require, exports, module) {
  //Will be the value 'large'
  var size = module.config().size;
});
//baz.js which uses a dependency array,
//it asks for the special module ID, 'module':
//https://github.com/jrburke/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#wiki-magic
define(['module'], function (module) {
  //Will be the value 'blue'
  var color = module.config().color;
});

若要將config傳給包,將目標(biāo)設(shè)置為包的主模塊而不是包ID:

requirejs.config({
  //Pass an API key for use in the pixie package'smain module.
  config: {
    'pixie/index': {
      apiKey: 'XJKDLNS'
    }
  },
  //Set up config for the "pixie" package, whose mainmodule is the index.js file in the pixie folder.
  packages: [
    {
      name: 'pixie',
      main: 'index'
    }
  ]
});

packages: 從CommonJS包(package)中加載模塊。

nodeIdCompat: 在放棄加載一個(gè)腳本之前等待的秒數(shù)。設(shè)為0禁用等待超時(shí)。默認(rèn)為7秒。

waitSeconds: 命名一個(gè)加載上下文。這允許require.js在同一頁(yè)面上加載模塊的多個(gè)版本,如果每個(gè)頂層require調(diào)用都指定了一個(gè)唯一的上下文字符串。

deps: 指定要加載的一個(gè)依賴(lài)數(shù)組。當(dāng)將require設(shè)置為一個(gè)config object在加載require.js之前使用時(shí)很有用。一旦require.js被定義,這些依賴(lài)就已加載。使用deps就像調(diào)用require([]),但它在loader處理配置完畢之后就立即生效。它并不阻塞其他的require()調(diào)用,它僅是指定某些模塊作為config塊的一部分而異步加載的手段而已。

callback: 在deps加載完畢后執(zhí)行的函數(shù)。當(dāng)將require設(shè)置為一個(gè)config object在加載require.js之前使用時(shí)很有用,其作為配置的deps數(shù)組加載完畢后為require指定的函數(shù)。

enforceDefine: 如果設(shè)置為true,則當(dāng)一個(gè)腳本不是通過(guò)define()定義且不具備可供檢查的shim導(dǎo)出字串值時(shí),就會(huì)拋出錯(cuò)誤。

xhtml: 如果設(shè)置為true,則使用document.createElementNS()去創(chuàng)建script元素。

urlArgs: RequireJS獲取資源時(shí)附加在URL后面的額外的query參數(shù)。作為瀏覽器或服務(wù)器未正確配置時(shí)的“cache bust”手段很有用。使用cache bust配置的一個(gè)示例:

urlArgs: "bust=" + (new Date()).getTime()

在開(kāi)發(fā)中這很有用,但請(qǐng)記得在部署到生成環(huán)境之前移除它。

scriptType: 指定RequireJS將script標(biāo)簽插入document時(shí)所用的type=""值。默認(rèn)為“text/javascript”。想要啟用Firefox的JavaScript 1.8特性,可使用值“text/javascript;version=1.8”。

§ 4 高級(jí)使用

§ 4.1 從包中加載模塊

RequireJS支持從CommonJS包結(jié)構(gòu)中加載模塊,但需要一些額外的配置。具體地,支持如下的CommonJS包特性:

一個(gè)包可以關(guān)聯(lián)一個(gè)模塊名/前綴。
package config可為特定的包指定下述屬性:
name: 包名(用于模塊名/前綴映射)
location: 磁盤(pán)上的位置。位置是相對(duì)于配置中的baseUrl值,除非它們包含協(xié)議或以“/”開(kāi)頭
main: 當(dāng)以“包名”發(fā)起require調(diào)用后,所應(yīng)用的一個(gè)包內(nèi)的模塊。默認(rèn)為“main”,除非在此處做了另外設(shè)定。該值是相對(duì)于包目錄的。

重要事項(xiàng)

雖然包可以有CommonJS的目錄結(jié)構(gòu),但模塊本身應(yīng)為RequireJS可理解的模塊格式。例外是:如果你在用r.js Node適配器,模塊可以是傳統(tǒng)的CommonJS模塊格式。你可以使用CommonJS轉(zhuǎn)換工具來(lái)將傳統(tǒng)的CommonJS模塊轉(zhuǎn)換為RequireJS所用的異步模塊格式。

一個(gè)項(xiàng)目上下文中僅能使用包的一個(gè)版本。你可以使用RequireJS的多版本支持來(lái)加載兩個(gè)不同的模塊上下文;但若你想在同一個(gè)上下文中使用依賴(lài)了不同版本的包C的包A和B,就會(huì)有問(wèn)題。未來(lái)可能會(huì)解決此問(wèn)題。
如果你使用了類(lèi)似于入門(mén)指導(dǎo)中的項(xiàng)目布局,你的web項(xiàng)目應(yīng)大致以如下的布局開(kāi)始(基于Node/Rhino的項(xiàng)目也是類(lèi)似的,只不過(guò)使用scripts目錄中的內(nèi)容作為項(xiàng)目的頂層目錄):

project-directory/
project.html
scripts/
require.js

而下面的示例中使用了兩個(gè)包,cart及store:

project-directory/
project.html
scripts/
cart/
main.js
store/
main.js
util.js
main.js
require.js

project.html 會(huì)有如下的一個(gè)script標(biāo)簽:

<script data-main="scripts/main" src="scripts/require.js"></script>

對(duì)“cart”的依賴(lài)請(qǐng)求會(huì)從scripts/cart/main.js中加載,因?yàn)椤癿ain”是RequireJS默認(rèn)的包主模塊。對(duì)“store/util”的依賴(lài)請(qǐng)求會(huì)從scripts/store/util.js加載。

如果“store”包不采用“main.js”約定,如下面的結(jié)構(gòu):

project-directory/
project.html
scripts/
cart/
main.js
store/
store.js
util.js
main.js
package.json
require.js

則RequireJS的配置應(yīng)如下:

require.config({
  packages: [
    "cart",
    {
      name: "store",
      main: "store"
    }
  ]
});

減少麻煩期間,強(qiáng)烈建議包結(jié)構(gòu)遵從“main.js”約定。

§ 4.2 多版本支持

 如配置項(xiàng)一節(jié)中所述,可以在同一頁(yè)面上以不同的“上下文”配置項(xiàng)加載同一模塊的不同版本。require.config()返回了一個(gè)使用該上下文配置的require函數(shù)。下面是一個(gè)加載不同版本(alpha及beta)模塊的示例(取自test文件中):

<script src="../require.js"></script>
<script>
var reqOne = require.config({
 context: "version1",
 baseUrl: "version1"
});
reqOne(["require", "alpha", "beta",],
function(require,  alpha,  beta) {
 log("alpha version is: " + alpha.version); //prints 1
 log("beta version is: " + beta.version); //prints 1

 setTimeout(function() {
  require(["omega"],
   function(omega) {
    log("version1 omega loaded with version: " +
       omega.version); //prints 1
   }
  );
 }, 100);
});
var reqTwo = require.config({
   context: "version2",
   baseUrl: "version2"
  });
reqTwo(["require", "alpha", "beta"],
function(require,  alpha,  beta) {
 log("alpha version is: " + alpha.version); //prints 2
 log("beta version is: " + beta.version); //prints 2
 setTimeout(function() {
  require(["omega"],
   function(omega) {
    log("version2 omega loaded with version: " +
      omega.version); //prints 2
   }
  );
 }, 100);
});
</script>

 注意“require”被指定為模塊的一個(gè)依賴(lài),這就允許傳遞給函數(shù)回調(diào)的require()使用正確的上下文來(lái)加載多版本的模塊。如果“require”沒(méi)有指定為一個(gè)依賴(lài),則很可能會(huì)出現(xiàn)錯(cuò)誤。

§ 4.3 在頁(yè)面加載之后加載代碼

上述多版本示例中也展示了如何在嵌套的require()中遲后加載代碼。

§ 4.4 Web Worker 支持

從版本0.12開(kāi)始,RequireJS可在Web Worker中運(yùn)行??梢酝ㄟ^(guò)在web worker中調(diào)用importScripts()來(lái)加載require.js(或包含require()定義的JS文件),然后調(diào)用require就好了。

你可能需要設(shè)置baseUrl配置項(xiàng)來(lái)確保require()可找到待加載腳本。

你可以在unit test使用的一個(gè)文件中找到一個(gè)例子。

§ 4.5 Rhino 支持

RequireJS可通過(guò)r.js適配器用在Rhino中。

§ 4.6 處理錯(cuò)誤

通常的錯(cuò)誤都是404(未找到)錯(cuò)誤,網(wǎng)絡(luò)超時(shí)或加載的腳本含有錯(cuò)誤。RequireJS有些工具來(lái)處理它們:require特定的錯(cuò)誤回調(diào)(errback),一個(gè)“paths”數(shù)組配置,以及一個(gè)全局的requirejs.onError事件。

傳入errback及requirejs.onError中的error object通常包含兩個(gè)定制的屬性:

requireType: 含有類(lèi)別信息的字串值,如“timeout”,“nodefine”, “scripterror”
requireModules: 超時(shí)的模塊名/URL數(shù)組。

如果你得到了requireModules錯(cuò),可能意味著依賴(lài)于requireModules數(shù)組中的模塊的其他模塊未定義。

§ 4.6.1 在IE中捕獲加載錯(cuò)

Internet Explorer有一系列問(wèn)題導(dǎo)致檢測(cè)errbacks/paths fallbacks中的加載錯(cuò) 比較困難:

IE 6-8中的script.onerror無(wú)效。沒(méi)有辦法判斷是否加載一個(gè)腳本會(huì)導(dǎo)致404錯(cuò);更甚地,在404中依然會(huì)觸發(fā)state為complete的onreadystatechange事件。

IE 9+中script.onerror有效,但有一個(gè)bug:在執(zhí)行腳本之后它并不觸發(fā)script.onload事件句柄。因此它無(wú)法支持匿名AMD模塊的標(biāo)準(zhǔn)方法。所以script.onreadystatechange事件仍被使用。但是,state為complete的onreadystatechange事件會(huì)在script.onerror函數(shù)觸發(fā)之前觸發(fā)。

因此IE環(huán)境下很難兩全其美:匿名AMD(AMD模塊機(jī)制的核心優(yōu)勢(shì))和可靠的錯(cuò)誤檢測(cè)。

但如果你的項(xiàng)目里使用了define()來(lái)定義所有模塊,或者為其他非define()的腳本使用shim配置指定了導(dǎo)出字串,則如果你將enforceDefine配置項(xiàng)設(shè)為true,loader就可以通過(guò)檢查define()調(diào)用或shim全局導(dǎo)出值來(lái)確認(rèn)腳本的加載無(wú)誤。

因此如果你打算支持Internet Explorer,捕獲加載錯(cuò),并使用了define()或shim,則記得將enforceDefine設(shè)置為true。參見(jiàn)下節(jié)的示例。

注意: 如果你設(shè)置了enforceDefine: true,而且你使用data-main=""來(lái)加載你的主JS模塊,則該主JS模塊必須調(diào)用define()而不是require()來(lái)加載其所需的代碼。主JS模塊仍然可調(diào)用require/requirejs來(lái)設(shè)置config值,但對(duì)于模塊加載必須使用define()。

§ 4.6.2 require([]) errbacks

當(dāng)與requirejs.undef()一同使用errback時(shí),允許你檢測(cè)模塊的一個(gè)加載錯(cuò),然后undefine該模塊,并重置配置到另一個(gè)地址來(lái)進(jìn)行重試。

一個(gè)常見(jiàn)的應(yīng)用場(chǎng)景是先用庫(kù)的一個(gè)CDN版本,如果其加載出錯(cuò),則切換到本地版本:

requirejs.config({
  enforceDefine: true,
  paths: {
    jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min'
  }
});
//Later
require(['jquery'], function ($) {
  //Do something with $ here
}, function (err) {
  //The errback, error callback
  //The error has a list of modules that failed
  var failedId = err.requireModules && err.requireModules[0];
  if (failedId === 'jquery') {
    //undef is function only on the global requirejs object.
    //Use it to clear internal knowledge of jQuery.
    //Any modules that were dependent on jQuery and in the middle of loading will not be loaded yet,
    //they will wait until a valid jQuerydoes load.
    requirejs.undef(failedId);
    //Set the path to jQuery to local path
    requirejs.config({
      paths: {
        jquery: 'local/jquery'
      }
    });
    //Try again. Note that the above require callback
    //with the "Do something with $ here" comment will
    //be called if this new attempt to load jQuery succeeds.
    require(['jquery'], function () {});
  } else {
    //Some other error. Maybe show message to the user.
  }
});

使用“requirejs.undef()”,如果你配置到不同的位置并重新嘗試加載同一模塊,則loader會(huì)將依賴(lài)于該模塊的那些模塊記錄下來(lái)并在該模塊重新加載成功后去加載它們。

注意: errback僅適用于回調(diào)風(fēng)格的require調(diào)用,而不是define()調(diào)用。define()僅用于聲明模塊。

§ 4.6.3 paths備錯(cuò)配置

上述模式(檢錯(cuò),undef()模塊,修改paths,重加載)是一個(gè)常見(jiàn)的需求,因此有一個(gè)快捷設(shè)置方式。paths配置項(xiàng)允許數(shù)組值:

requirejs.config({
  //To get timely, correct error triggers in IE, force a define/shim exports check.
  enforceDefine: true,
  paths: {
    jquery: [
      'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min',
      //If the CDN location fails, load from this location
      'lib/jquery'
    ]
  }
});
//Later
require(['jquery'], function ($) {
});

上述代碼先嘗試加載CDN版本,如果出錯(cuò),則退回到本地的lib/jquery.js。

注意: paths備錯(cuò)僅在模塊ID精確匹配時(shí)工作。這不同于常規(guī)的paths配置,常規(guī)配置可匹配模塊ID的任意前綴部分。備錯(cuò)主要用于非常的錯(cuò)誤恢復(fù),而不是常規(guī)的path查找解析,因?yàn)槟窃跒g覽器中是低效的。

§ 4.6.4 全局 requirejs.onError

為了捕獲在局域的errback中未捕獲的異常,你可以重載requirejs.onError():

requirejs.onError = function (err) {
  console.log(err.requireType);
  if (err.requireType === 'timeout') {
    console.log('modules: ' + err.requireModules);
  }
  throw err;
};

§ 5.加載插件

RequireJS支持加載器插件。使用它們能夠加載一些對(duì)于腳本正常工作很重要的非JS文件。RequireJS的wiki有一個(gè)插件的列表。本節(jié)討論一些由RequireJS一并維護(hù)的特定插件:

§ 5.1 指定文本文件依賴(lài)

如果都能用HTML標(biāo)簽而不是基于腳本操作DOM來(lái)構(gòu)建HTML,是很不錯(cuò)的。但沒(méi)有好的辦法在JavaScript文件中嵌入HTML。所能做的僅是在js中使用HTML字串,但這一般很難維護(hù),特別是多行HTML的情況下。.

RequireJS有個(gè)text.js插件可以幫助解決這個(gè)問(wèn)題。如果一個(gè)依賴(lài)使用了text!前綴,它就會(huì)被自動(dòng)加載。參見(jiàn)text.js的README文件。

§ 5.2 頁(yè)面加載事件及DOM Ready

RequireJS加載模塊速度很快,很有可能在頁(yè)面DOM Ready之前腳本已經(jīng)加載完畢。需要與DOM交互的工作應(yīng)等待DOM Ready?,F(xiàn)代的瀏覽器通過(guò)DOMContentLoaded事件來(lái)知會(huì)。

但是,不是所有的瀏覽器都支持DOMContentLoaded。domReady模塊實(shí)現(xiàn)了一個(gè)跨瀏覽器的方法來(lái)判定何時(shí)DOM已經(jīng)ready。下載并在你的項(xiàng)目中如此用它:

require(['domReady'], function (domReady) {
 domReady(function () {
  //This function is called once the DOM is ready.
  //It will be safe to query the DOM and manipulateDOM nodes in this function.
 });
});

基于DOM Ready是個(gè)常規(guī)需求,像上述API中的嵌套調(diào)用方式,理想情況下應(yīng)避免。domReady模塊也實(shí)現(xiàn)了Loader Plugin API,因此你可以使用loader plugin語(yǔ)法(注意domReady依賴(lài)的!前綴)來(lái)強(qiáng)制require()回調(diào)函數(shù)在執(zhí)行之前等待DOM Ready。當(dāng)用作loader plugin時(shí),domReady會(huì)返回當(dāng)前的document:

require(['domReady!'], function (doc) {
  //This function is called once the DOM is ready,
  //notice the value for 'domReady!' is the currentdocument.
});

注意: 如果document需要一段時(shí)間來(lái)加載(也許是因?yàn)轫?yè)面較大,或加載了較大的js腳本阻塞了DOM計(jì)算),使用domReady作為loader plugin可能會(huì)導(dǎo)致RequireJS“超時(shí)”錯(cuò)。如果這是個(gè)問(wèn)題,則考慮增加waitSeconds配置項(xiàng)的值,或在require()使用domReady()調(diào)用(將其當(dāng)做是一個(gè)模塊)。

以上是“RequireJs如何使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

名稱(chēng)欄目:RequireJs如何使用
文章起源:http://newbst.com/article42/jhsphc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)站策劃、ChatGPT軟件開(kāi)發(fā)、網(wǎng)站收錄、域名注冊(cè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化