摘要:再者,引入一大堆的文件也不美觀,而使用即可實(shí)現(xiàn)的模塊化異步加載。通過定義模塊的方式可分為以下兩類。當(dāng)和這兩個(gè)模塊加載完成之后將會(huì)執(zhí)行回調(diào)函數(shù)。插件可以使回調(diào)函數(shù)在結(jié)構(gòu)加載完成之后再執(zhí)行。最好的方式是使用字符串但這很難管理尤其實(shí)在多行的時(shí)候。
什么是Require.js
Require.js是一個(gè)AMD規(guī)范的輕量級(jí)js模塊化管理框架,最新版本require.js 2.1.11壓縮后只有14.88K,它可以把js代碼分成一個(gè)個(gè)模塊,實(shí)現(xiàn)異步或動(dòng)態(tài)加載,還能很清晰的看出模塊之間的依賴,從而提高代碼質(zhì)量,性能和可維護(hù)性。Require.js的作者是AMD規(guī)范的創(chuàng)始人 James Burke。
Require.js能帶來什么好處下面我們可以舉一個(gè)簡(jiǎn)單的例子說明:
通常我們的頁面結(jié)構(gòu)是以下這樣
require require
a.js里面的代碼
alert("require");
當(dāng)運(yùn)行頁面可以發(fā)現(xiàn)當(dāng)彈出alert時(shí)需要點(diǎn)擊確定才會(huì)顯示div的內(nèi)容,因?yàn)轫撁娴膉s是同步渲染,js的渲染必然會(huì)阻塞后面的html渲染。再者,引入一大堆的js文件也不美觀,而使用require.js即可實(shí)現(xiàn)js的模塊化異步加載。
如何使用Require.js先到require.js官網(wǎng)下載最新版本,然后引入到頁面,如下:
data-main屬性不能忽略,data-main指向的文件是主代碼所在的文件,main.js里面配置的腳本都將是異步加載,main.js所在的目錄默認(rèn)為根路徑。
require.js configconfig方法用于配置運(yùn)行參數(shù)。首先設(shè)置參數(shù),看下面的例子:
我的項(xiàng)目文件結(jié)構(gòu)如下
主文件main.js
require.config({ baseUrl: "js", paths: { "jquery": ["lib/jquery-1.8.3.min"], "popup": ["lib/popup"], "moduleA": ["app/moduleA"], "moduleB": ["appmoduleB"] }, shim: { "popup": { deps: ["jquery"] } } });
config方法接收一個(gè)對(duì)象參數(shù),以下解釋各屬性作用。
baseUrl:設(shè)置根路徑,如沒有設(shè)置該屬性則默認(rèn)為主文件所在的目錄,這里設(shè)置JS目錄為根路徑。
paths:設(shè)置各模塊的別名和路徑,在調(diào)用模塊時(shí)需使用別名。資源文件路徑可以是本地路徑,也可以是外部的鏈接,也可以設(shè)置多個(gè)路徑,路徑可以是一個(gè)字符串路徑,也可以是一個(gè)數(shù)組,當(dāng)存在兩個(gè)或以上路徑時(shí)必須是數(shù)組。
以JQ路徑為例,單個(gè)路徑"jquery": ["lib/jquery-1.8.3.min"]
多個(gè)路徑"jquery": ["http://apps.bdimg.com/libs/jquery/1.8.3/jquery.min.js","lib/jquery-1.8.3.min"],多個(gè)路徑時(shí)會(huì)先獲取第一個(gè)路徑的資源文件,第一個(gè)路徑加載失敗則會(huì)加載第二個(gè)路徑(注意:本人實(shí)踐中第一個(gè)路徑使用CDN時(shí)在IE11以下的IE瀏覽器會(huì)加載失敗且沒有調(diào)用本地資源,原因未知)
shim:非AMD規(guī)范的模塊不能直接調(diào)用,該屬性用于設(shè)置非AMD規(guī)范的模塊,屬性值是一個(gè)對(duì)象,本人寫的彈框插件非AMD規(guī)范因此需要設(shè)置,設(shè)置的模塊名稱和所依賴的模塊名稱需是該模塊在paths定義的別名。deps用于設(shè)置該模塊的依賴,popup插件依賴于JQ
單從語義就應(yīng)該猜到這個(gè)函數(shù)用來定于模塊,下面解釋define函數(shù),若看不懂別著急,后面會(huì)舉例。
在require.js源碼中可以看到有這么一行代碼define = function (name, deps, callback) {} ,可知define接收三個(gè)參數(shù)
name:為可選參數(shù),該模塊的標(biāo)識(shí),字符串類型,通俗來講就是給該模塊取的名稱,可自定義,但不能與其他模塊名稱相同,如果該參數(shù)未選,那么該模塊的名稱為該文件在paths中定義的別名
deps:當(dāng)前模塊的依賴,數(shù)組類型,為已定義的模塊名稱,若不存在依賴該參數(shù)可不填
callback:是一個(gè)函數(shù)或者對(duì)象,為函數(shù)時(shí),當(dāng)依賴的模塊加載完成后該回調(diào)函數(shù)將被調(diào)用,依賴關(guān)系會(huì)以參數(shù)的形式注入到該函數(shù)上,參數(shù)與依賴的模塊一一對(duì)應(yīng),(注:如果定義的模塊想被其他模塊引用需返回一個(gè)對(duì)象)。
通過define定義模塊的方式可分為以下兩類。
1. 無依賴模塊
也就是說該模塊無需依賴其他模塊,可以直接定義,如下:
例1
define({ fnMethod: function() { return ("這是一個(gè)無依賴模塊") } });
該模塊只傳了一個(gè)對(duì)象類型的callback,也等價(jià)于
例2
define(function() { return { fnMethod: function () { return ("這是一個(gè)無依賴模塊") } } });
該模塊則傳了一個(gè)函數(shù)類型的callback,模塊定義了一個(gè)函數(shù)fnMethod,返回一個(gè)字符串值,實(shí)際上返回值也可以是其他類型,第二種方法只是將函數(shù)做為對(duì)象返回,建議采用第二種方法來定義無依賴模塊。
2. 有依賴模塊
定義有依賴模塊格式需要稍作改變,格式如下:
例3
//假如moduleA模塊返回了一個(gè)屬性name,值為“老宋”,老馬define(["jquery","moduleA"],function($, mA) { //參數(shù)和依賴的模塊需一一對(duì)應(yīng) return { fnMethod: function () { return ($.text(".text") + mA.name); } } });
該例子表明當(dāng)前模塊依賴于jquery和moduleA,返回一個(gè)結(jié)果“老馬老宋”。
沿用上面的例子再舉一個(gè)完整的例子:
例4
define("module",["jquery","moduleA"],function($, mA) { //參數(shù)和依賴的模塊需一一對(duì)應(yīng) return { fnMethod: function () { //fnMethod即提供給外部調(diào)用的接口 return ($(".text").text() + mA.name); } } });
這里定義了一個(gè)名為module的模塊,并且它依賴于jquery和moduleA模塊。
當(dāng)依賴的模塊很多的時(shí)候再像下面這樣寫感覺是不是很挫?
例5
define("module", ["jquery", "moduleA", "moduleB", "moduleC", "moduleD", "moduleE", "moduleF"], function ($, mA, mB, mC, mD, mE, mF) { return { fnMethod: function () { return ($(".text").text() + mA.name); } } });
require.js2.0版本之后提供了一種更好的寫法。
例6
define("module", function (require) { //將“require”本身做為一個(gè)依賴注入到模塊 var $ = require("jquery"), mA = require("moduleA"), mB = require("moduleB"), mC = require("moduleC"), mD = require("moduleD"), mE = require("moduleE"), mF = require("moduleF"); return { fnMethod: function () { return ($(".text").text() + mA.name); } } });
注意以下幾點(diǎn):
1.當(dāng)要在define內(nèi)部使用require時(shí),需將“require”本身做為一個(gè)依賴注入到模塊,如例6,例5有依賴則可在依賴數(shù)組中加入,如無依賴不應(yīng)將require加入依賴數(shù)組會(huì)報(bào)錯(cuò),而要像例6一樣做法。
2.require.js要求一個(gè)文件一個(gè)模塊,意思就是一個(gè)文件只能有一個(gè)define定義的模塊,如果一個(gè)文件存在多個(gè)define模塊,也只會(huì)識(shí)別第一個(gè)(如果模塊寫在主文件則是另外一種情況,優(yōu)化部分會(huì)講解),上面例子的moduleA和moduleB等應(yīng)存在不同文件中,define如果填了name參數(shù),該name的名稱必須與paths中該文件的別名一致。
require()用來調(diào)用模塊,使用方法與define()類似,require.js源碼中有這么一行return context.require(deps, callback, errback),可知require()也有三個(gè)參數(shù)。
require(["moduleA", "moduleB"], function (mA, mB) { console.log(mA.name); console.log(mB.age); }, function (error) { //.... } );
當(dāng)moduleA和moduleB這兩個(gè)模塊加載完成之后將會(huì)執(zhí)行回調(diào)函數(shù)。
第一個(gè)參數(shù)依然是依賴關(guān)系數(shù)組;
第二個(gè)參數(shù)是依賴加載成功后的回調(diào)函數(shù);
第三個(gè)參數(shù)則是處理錯(cuò)誤的回調(diào)函數(shù),接收一個(gè)error對(duì)象參數(shù),require對(duì)象還允許指定一個(gè)全局性的Error事件的監(jiān)聽函數(shù)。所有沒有被上面的方法捕獲的錯(cuò)誤,都會(huì)被觸發(fā)這個(gè)監(jiān)聽函數(shù)。
requirejs.onError = function (error) { // ...... };
require也可以下在define內(nèi)部使用,如下:
define("moduleA",function (require) { //....... require(["moduleB, moduleC"], function(mB, mC) { //....... }); //..... });
require可以直接調(diào)用JSONP模式,只需將callback參數(shù)的值指定為"define",
require(["http://example.com/api/data.json?callback=define"], function (data) { console.log(data); } );
上面是一個(gè)調(diào)用JSONP的示例,該例子中,JSONP的callback參數(shù)為"callback",因此"callback=define"告訴API將JSON響應(yīng)包裹到一個(gè)"define()"中,JSONP的這種用法應(yīng)僅限于應(yīng)用的初始化中,一旦JSONP服務(wù)超時(shí),其他通過define()定義了的模塊也可能得不得執(zhí)行。
僅支持返回值類型為JSON object的JSONP服務(wù),其他返回類型如數(shù)組、字串、數(shù)字等都不能支持。
require.js支持加載插件,用來加載其他非JS文件,下載插件并將它放在應(yīng)用程序的baseUrl目錄(如果想放在其他地方,使用paths config 進(jìn)行配置),更多更詳細(xì)的插件可查看官方文檔,示例以domReady插件,text插件為例。
domReady插件可以使回調(diào)函數(shù)在DOM結(jié)構(gòu)加載完成之后再執(zhí)行。
require(["domReady"], function (domReady) { domReady(function () { //This function is called once the DOM is ready. //It will be safe to query the DOM and manipulate //DOM nodes in this function. }); });
require(["domready!"], function (doc){ //This function is called once the DOM is ready. //It will be safe to query the DOM and manipulate //DOM nodes in this function. });
text.js插件
相比于使用script構(gòu)建DOM結(jié)構(gòu),使用HTML標(biāo)簽來構(gòu)建html是一個(gè)很好的方式。然而, 并沒有很好的方式可以在js文件中嵌入 HTML 。最好的方式是使用 HTML字符串, 但這很難管理,尤其實(shí)在多行HTML的時(shí)候。text.js 能解決這個(gè)問題,如果依賴添加了 text!前綴它將會(huì)被自動(dòng)加載。
require(["text!/view/index.html" ,"text!/css/tab.css"], function(html, css) { //........ } );
上面示例加載的文件內(nèi)容將以字符串的形式存在變量中。
優(yōu)化文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/80934.html
摘要:二模塊化規(guī)范概述應(yīng)用由模塊組成,采用模塊規(guī)范。模塊化語法命令用于規(guī)定模塊的對(duì)外接口,命令用于輸入其他模塊提供的功能。 前言 在JavaScript發(fā)展初期就是為了實(shí)現(xiàn)簡(jiǎn)單的頁面交互邏輯,寥寥數(shù)語即可;如今CPU、瀏覽器性能得到了極大的提升,很多頁面邏輯遷移到了客戶端(表單驗(yàn)證等),隨著web2.0時(shí)代的到來,Ajax技術(shù)得到廣泛應(yīng)用,jQuery等前端庫層出不窮,前端代碼日益膨脹,此時(shí)...
摘要:二模塊化規(guī)范概述應(yīng)用由模塊組成,采用模塊規(guī)范。模塊化語法命令用于規(guī)定模塊的對(duì)外接口,命令用于輸入其他模塊提供的功能。 前言 在JavaScript發(fā)展初期就是為了實(shí)現(xiàn)簡(jiǎn)單的頁面交互邏輯,寥寥數(shù)語即可;如今CPU、瀏覽器性能得到了極大的提升,很多頁面邏輯遷移到了客戶端(表單驗(yàn)證等),隨著web2.0時(shí)代的到來,Ajax技術(shù)得到廣泛應(yīng)用,jQuery等前端庫層出不窮,前端代碼日益膨脹,此時(shí)...
摘要:規(guī)范則是非同步加載模塊,允許指定回調(diào)函數(shù),可以實(shí)現(xiàn)異步加載依賴模塊,并且會(huì)提前加載由于主要用于服務(wù)器編程,模塊文件一般都已經(jīng)存在于本地硬盤,所以加載起來比較快,不用考慮非同步加載的方式,所以規(guī)范比較適用。 JS模塊化 模塊化的理解 什么是模塊? 將一個(gè)復(fù)雜的程序依據(jù)一定的規(guī)則(規(guī)范)封裝成幾個(gè)塊(文件), 并進(jìn)行組合在一起; 塊的內(nèi)部數(shù)據(jù)/實(shí)現(xiàn)是私有的, 只是向外部暴露一些接口(...
摘要:這是局部安裝局部安裝的使用要帶路徑哇,要寫路徑,好麻煩哦,沒事,那就全局安裝吧。如果該值是一個(gè)相對(duì)路徑,它將相對(duì)于包含的文件。就相當(dāng)于就相當(dāng)于就相當(dāng)于后面帶有意味著要完全匹配如果,因?yàn)闆]完全匹配,那么加載的是下文件夾里的使用教程二 Webpack是什么,我就不過多介紹了,大家都有耳聞,不過還是配張圖讓大家體會(huì)下。showImg(https://segmentfault.com/img/...
摘要:要求模塊編寫必須在真正的代碼之外套上一層規(guī)定的代碼包裝,樣子看起來是這樣的模塊代碼通過傳遞一個(gè)簽名為的回調(diào)函數(shù)給函數(shù),就可以把需要注入的變量和函數(shù)注入到模塊代碼內(nèi)。 之前寫的文章急速Js全棧教程得到了不錯(cuò)的閱讀量,霸屏掘金頭條3天,點(diǎn)贊過千,閱讀近萬,甚至還有人在評(píng)論區(qū)打廣告,可見也是一個(gè)小小的生態(tài)了;)??磥砗蚃S全棧有關(guān)的內(nèi)容,還是有人頗有興趣的。 showImg(https://...
閱讀 3864·2021-08-30 09:47
閱讀 3855·2019-08-30 15:56
閱讀 734·2019-08-30 14:18
閱讀 760·2019-08-29 16:17
閱讀 2115·2019-08-29 11:07
閱讀 690·2019-08-26 13:53
閱讀 3504·2019-08-26 10:26
閱讀 2546·2019-08-23 18:30