摘要:概述強大靈活的運用是通過配置文件決定的。下面通過示例來進行深度的探討配置文件的使用。配置文件的位置配置文件的位置和聲明用法是相對于這個腳本文件來決定的。配置文件參數的介紹所有模塊的查找根路徑。
概述
Requires強大靈活的運用是通過配置文件決定的。通過配置文件我們可以給模塊取別名、給模塊加上版本標識、設置模塊依賴、包裝非模塊等強大功能。同時RequireJS的優化器也大量使用了配置選項,如果你使用grunt、gulp等構建工具的話,也有必要深入的學習配置文件的使用。
下面通過示例來進行深度的探討配置文件的使用。
配置文件的位置配置文件的位置和聲明用法是相對于Requires這個腳本文件來決定的。假如配置文件在Requires腳本的下方,則可以這樣使用:
這種情況一般都是把配置參數寫到require.config里面。如果配置文件在Requires腳本的上面,則是另外一種用法了,示例代碼如下所示:
這種情況下由于require.js后加載,那么直接使用require.config就會報錯,這時候就只能通過聲明一個全局的變量來注入配置參數來實現了。
這時,你可能會發問了,改用那種情況呢?我只能說根據你具體的業務來選擇某種場景。配置是活的,人也是活得。業務也是活的,所以這個沒有統一的答案,再有甚者,你可以兩個結合使用。
除了要注意配置文件的位置要靈活使用之外,以下有幾點還是要注意的,這算是最佳實踐吧。
配置文件多帶帶成一個文件,不要跟具體的業務模塊耦合。
最好使用 var require = {} 的形式而不是 window.require = {}的形式。后者在IE中運行不正常。
在決定配置位置后,下面就是配置文件的參數了,RequireJS包含了大量的參數,這也是配置文件的核心,具體明細如下。
配置文件參數的介紹 baseUrl所有模塊的查找根路徑。所以上面的示例中,"my/module"的標簽src值是"/another/path/my/module.js"。當加載純.js文件(依賴字串以/開頭,或者以.js結尾,或者含有協議),不會使用baseUrl。因此a.js及b.js都在包含上述代碼段的HTML頁面的同目錄下加載。
如未顯式設置baseUrl,則默認值是加載require.js的HTML所處的位置。如果用了data-main屬性,則該路徑就變成baseUrl。(所以最佳實踐還是推重使用baseUrl)
baseUrl可跟require.js頁面處于不同的域下,RequireJS腳本的加載是跨域的。唯一的限制是使用text! plugins加載文本內容時,這些路徑應跟頁面同域,至少在開發時應這樣。優化工具會將text! plugin資源內聯,因此在使用優化工具之后你可以使用跨域引用text! plugin資源的那些資源。
pathspath映射那些不直接放置于baseUrl下的模塊名(這相當于跟冗長的模塊名取個簡介的名字)。設置path時起始位置是相對于baseUrl的,除非該path設置以"/"開頭或含有URL協議(如http:)。在上述的配置下,"some/module"的script標簽src值是"/another/path/some/v1.0/module.js"。
用于模塊名的path不應含有.js后綴,因為一個path有可能映射到一個目錄。路徑解析機制會自動在映射模塊名到path時添加上.js后綴。在文本模版之類的場景中使用require.toUrl()時它也會添加合適的后綴。
在瀏覽器中運行時,可指定路徑的備選(fallbacks),以實現諸如首先指定了從CDN中加載,一旦CDN加載失敗則從本地位置中加載這類的機制。(回調函數,這個可以跟蹤腳本加載是否成功。)
ps:paths映射的模塊不一定是標準的AMD模塊,但是最佳實踐推薦是有意義的模塊。
shim為那些沒有使用define()來聲明依賴關系、設置模塊的"瀏覽器全局變量注入"型腳本做依賴和導出配置。
下面有個示例,它需要 RequireJS 2.1.0+,并且假定backbone.js、underscore.js 、jquery.js都裝于baseUrl目錄下。如果沒有,則你可能需要為它們設置paths config:
requirejs.config({ //Remember: only use shim config for non-AMD scripts, //scripts that do not already call define(). The shim //config will not work correctly if used on AMD scripts, //in particular, the exports and init config will not //be triggered, and the deps config will be confusing //for those cases. shim: { "backbone": { //These script dependencies should be loaded before loading //backbone.js deps: ["underscore", "jquery"], //Once loaded, use the global "Backbone" as the //module value. exports: "Backbone" }, "underscore": { exports: "_" }, "foo": { deps: ["bar"], exports: "Foo", init: function (bar) { //Using a function allows you to call noConflict for //libraries 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 value //instead 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 section //below for an approach for jQuery. return this.Foo.noConflict(); } } } }); //Then, later in a separate file, call it "MyModel.js", a module is //defined, specifying "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"屬性可以是一個函數而不是字串。這種情況下它就起到上述示例中的"init"屬性的功能。 RequireJS 2.1.0+中加入了"init"承接庫加載后的初始工作,以使exports作為字串值被enforceDefine所使用。
那些僅作為jQuery或Backbone的插件存在而不導出任何模塊變量的"模塊"們,shim配置可簡單設置為依賴數組:
requirejs.config({ shim: { "jquery.colorize": ["jquery"], "jquery.scroll": ["jquery"], "backbone.layoutmanager": ["backbone"] } });
但請注意,若你想在IE中使用404加載檢測以啟用path備選(fallbacks)或備錯(errbacks),則需要給定一個字串值的exports以使loader能夠檢查出腳本是否實際加載了(init中的返回值不會用于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"配置的重要注意事項:
shim配置僅設置了代碼的依賴關系,想要實際加載shim指定的或涉及的模塊,仍然需要一個常規的require/define調用。設置shim本身不會觸發代碼的加載。
請僅使用其他"shim"模塊作為shim腳本的依賴,或那些沒有依賴關系,并且在調用define()之前定義了全局變量(如jQuery或lodash)的AMD庫。否則,如果你使用了一個AMD模塊作為一個shim配置模塊的依賴,在build之后,AMD模塊可能在shim托管代碼執行之前都不會被執行,這會導致錯誤。終極的解決方案是將所有shim托管代碼都升級為含有可選的AMD define()調用。
"shim"配置的優化器重要注意事項:
您應當使用 mainConfigFile build配置項來指定含有shim配置的文件位置,否則優化器不會知曉shim配置。另一個手段是將shim配置復制到build profile中。
不要在一個build中混用CDN加載和shim配置。示例場景,如:你從CDN加載jQuery的同時使用shim配置加載依賴于jQuery的原版Backbone。不要這么做。您應該在build中將jQuery內聯而不是從CDN加載,否則build中內聯的Backbone會在CDN加載jQuery之前運行。這是因為shim配置僅延時加載到所有的依賴已加載,而不會做任何define的自動裝裹(auto-wrapping)。在build之后,所有依賴都已內聯,shim配置不能延時執行非define()的代碼。define()的模塊可以在build之后與CDN加載代碼一并工作,因為它們已將自己的代碼合理地用define裝裹了,在所有的依賴都已加載之前不會執行。因此記住:shim配置僅是個處理非模塊(non-modular)代碼、遺留代碼的將就手段,如可以應盡量使用define()的模塊。
對于本地的多文件build,上述的CDN加載建議仍然適用。任何shim過的腳本,它們的依賴必須加載于該腳本執行之前。這意味著要么直接在含有shim腳本的build層build它的依賴,要么先使用require([], function (){})調用來加載它的依賴,然后對含有shim腳本的build層發出一個嵌套的require([])調用。
如果您使用了uglifyjs來壓縮代碼,不要將uglify的toplevel選項置為true,或在命令行中不要使用 -mt。 該選項會破壞shim用于找到exports的全局名稱。
ps:shim配置是所有配置中最繁瑣也是最容易出問題的選項,我一般用來處理css依賴,最佳實踐是能不用,盡量不用shim配置。
map對于給定的模塊前綴,使用一個不同的模塊ID來加載該模塊。
該手段對于某些大型項目很重要:如有兩類模塊需要使用不同版本的"foo",但它們之間仍需要一定的協同。 在那些基于上下文的多版本實現中很難做到這一點。而且,paths配置僅用于為模塊ID設置root paths,而不是為了將一個模塊ID映射到另一個。
map示例:
requirejs.config({ map: { "some/newmodule": { "foo": "foo1.2" }, "some/oldmodule": { "foo": "foo1.0" } } });
如果各模塊在磁盤上分布如下:
foo1.0.js
foo1.2.js
some/
newmodule.js
oldmodule.js
當“some/newmodule”調用了“require("foo")”,它將獲取到foo1.2.js文件;而當“some/oldmodule”調用“`require("foo")”時它將獲取到foo1.0.js。
該特性僅適用于那些調用了define()并將其注冊為匿名模塊的真正AMD模塊腳本。并且,請在map配置中僅使用絕對模塊ID,“../some/thing”之類的相對ID不能工作。
另外在map中支持“*”,意思是“對于所有的模塊加載,使用本map配置”。如果還有更細化的map配置,會優先于“*”配置。示例:
requirejs.config({ map: { "*": { "foo": "foo1.2" }, "some/oldmodule": { "foo": "foo1.0" } } });
意思是除了“some/oldmodule”外的所有模塊,當要用“foo”時,使用“foo1.2”來替代。對于“some/oldmodule”自己,則使用“foo1.0”。
PS:map提供了統一腳本,不同版本的支持。
config常常需要將配置信息傳給一個模塊。這些配置往往是application級別的信息,需要一個手段將它們向下傳遞給模塊。在RequireJS中,基于requirejs.config()的config配置項來實現。要獲取這些信息的模塊可以加載特殊的依賴“module”,并調用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傳給包,將目標設置為包的主模塊而不是包ID:
requirejs.config({ //Pass an API key for use in the pixie package"s //main module. config: { "pixie/index": { apiKey: "XJKDLNS" } }, //Set up config for the "pixie" package, whose main //module is the index.js file in the pixie folder. packages: [ { name: "pixie", main: "index" } ] });
PS: config在我的項目中沒有被用到過,不過值得關注,另外對于第二種情況,本人不太熟悉,后期會開一篇文章介紹。
packages從CommonJS包(package)中加載模塊。參見從包中加載模塊。(鏈接:http://requirejs.cn/docs/commonjs.html)
PS:目前還沒遇到這樣的場景,關注中...
nodeIdCompatNode treats module ID example.js and example the same. By default these are two different IDs in RequireJS. If you end up using modules installed from npm, then you may need to set this config value to true to avoid resolution issues。
(翻譯:Node對待模塊example.js和example是一樣的.默認在RequireJS中有兩個不同的標識。如果你通過npm安裝且使用模塊結束,那么你可能需要設置這個參數為true來避免這個問題。)
waitSeconds在放棄加載一個腳本之前等待的秒數。設為0禁用等待超時。默認為7秒。
context命名一個加載上下文。這允許require.js在同一頁面上加載模塊的多個版本,如果每個頂層require調用都指定了一個唯一的上下文字符串。想要正確地使用,請參考多版本支持一節。
deps指定要加載的一個依賴數組。當將require設置為一個config object在加載require.js之前使用時很有用。一旦require.js被定義,這些依賴就已加載。使用deps就像調用require([]),但它在loader處理配置完畢之后就立即生效。它并不阻塞其他的require()調用,它僅是指定某些模塊作為config塊的一部分而異步加載的手段而已。
callback在deps加載完畢后執行的函數。當將require設置為一個config object在加載require.js之前使用時很有用,其作為配置的deps數組加載完畢后為require指定的函數。
enforceDefine如果設置為true,則當一個腳本不是通過define()定義且不具備可供檢查的shim導出字串值時,就會拋出錯誤。參考在IE中捕獲加載錯誤一節。
xhtml如果設置為true,則使用document.createElementNS()去創建script元素。
urlArgsRequireJS獲取資源時附加在URL后面的額外的query參數。作為瀏覽器或服務器未正確配置時的“cache bust”手段很有用。使用cache bust配置的一個示例:
urlArgs: "bust=" + (new Date()).getTime()
在開發中這很有用,但請記得在部署到生成環境之前移除它。
scriptType指定RequireJS將script標簽插入document時所用的type=""值。默認為“text/javascript”。想要啟用Firefox的JavaScript 1.8特性,可使用值“text/javascript;version=1.8”。
skipDataMainIntroduced in RequireJS 2.1.9: If set to true, skips the data-main attribute scanning done to start module loading. Useful if RequireJS is embedded in a utility library that may interact with other RequireJS library on the page, and the embedded version should not do data-main loading.
(翻譯:在2.1.9中被引入:如果設置為true,就會跳過data-main屬性的掃描啟動模塊的加載。如果RequireJS嵌入到一個通用的庫中以其他頁面中的RequireJS交互,且嵌入的版本不會使用data-main加載)
PS:翻譯不標準,請告知,另外這個屬性用的不多,暫時沒什么實踐經驗。
幫助文檔官網:http://requirejs.org/docs/api.html#config
中文翻譯:http://requirejs.cn/docs/api.html#config
ps:翻譯不標準、涉及文章侵權、文章有錯誤的地方請告知。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64183.html
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
摘要:所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。 1.模塊的寫法 模塊化編程一般都有這么幾個過渡過程,如下描述。 原始方法 function m1(){ //... } function m2(){ //... } 上面的函數m1()和m2(),組成一個模塊。使用的時候,直接調用就行了。 這種做法的缺點很明顯:污染了全局變量,無法保證不與...
摘要:將模塊定義為一個函數對模塊的返回值類型并沒有強制為一定是個,任何函數的返回值都是允許的。此處是一個返回了函數的模塊定義點評加載該模塊后,返回值是一個閉包。僅支持返回值類型為的服務,其他返回類型如數組字串數字等都不能支持。 概述 模塊不同于傳統的腳本文件,它良好地定義了一個作用域來避免全局名稱空間污染。它可以顯式地列出其依賴關系,并以函數(定義此模塊的那個函數)參數的形式將這些依賴進行...
摘要:在對象的構造函數中,將一個函數作為第一個參數。二對象中的方法,可以接收構造函數中處理的狀態變化,并分別對應執行。 showImg(https://segmentfault.com/img/remote/1460000008932857); Promise的重要性我認為我沒有必要多講,概括起來說就是必須得掌握,而且還要掌握透徹。這篇文章的開頭,主要跟大家分析一下,為什么會有Promise...
摘要:模塊化工具學習文檔作為一個開發者,原來寫代碼都是流水賬式的,一直想寫出模塊化的,但是前端工具多如牛毛,確都是針對于的打包工具。之中導入對應模塊即可。如果設為,則禁用等待超時。 JS模塊化工具 requirejs 學習文檔 作為一個Java開發者,原來寫js代碼都是流水賬式的,一直想寫出模塊化的js,但是前端工具多如牛毛,確都是針對于nodejs的打包工具。但是我在實際的開發過程中,并沒...
閱讀 2197·2021-11-25 09:43
閱讀 1165·2021-11-23 09:51
閱讀 3499·2021-11-23 09:51
閱讀 3628·2021-11-22 09:34
閱讀 1543·2021-10-09 09:43
閱讀 2119·2019-08-30 15:53
閱讀 3161·2019-08-30 14:07
閱讀 568·2019-08-28 18:14