javascript
JS三教九流系列-require.js-网站模块化开发
為什么80%的碼農都做不了架構師?>>> ??
js開發的模塊化就是module處理
簡單理解js模塊化的開發就是讓我們的web項目對js進行分類的處理
我們在開發網站的時候,里面會用要很多的類庫,如jquery,還會有到基于jq各種插件,還會有其他類庫,還有自己寫的js或者jq代碼等。一個html頁面會有n多個script標簽對外部js的引用,是不是感覺這樣的頁面會非常的混亂,如果我們可以只用一個script標簽載入一個js文件,這個js文件把其他需要的js文件能全部加載進去,并且按著之間依賴關系執行,是不是一個頁面就非常的整潔和容易擴展處理。
js的開發規范有AMD,典型代表就是require.js
CMD,典型代表就是sear.js
Commonjs規范我們已經接觸過,在nodejs的安裝和使用中我們在頁面里運用require()請求原生模塊、第三方模塊和export定義我們第三方模塊就是在運用commonjs的規范開發
我們的requirejs就是典型的amd規范處理,實現html頁面中head.appendchild("script")的加載和內部依賴順序處理
amd是異步加載模塊化開發,采用異步的載入方式,也就是我們雖然先引用了require.js,下面的js文件也可能先執行處理,如果對上面有依賴,也可能失效。
我們通過參考requriejs的手冊,去實踐到我們的網頁開發中去,利用amd模塊化的技術去開發我們的網頁。
requirejs文檔地址 http://www.requirejs.cn/?
requirejs下載地址 http://apps.bdimg.com/libs/require.js/2.1.11/require.min.js
咱們不去學習那么多的高級處理,基礎功能已經足夠我們的項目開發,一切為了開發去使用
下載requirejs,加載到html頁面中,通過script標簽的src屬性加載require.js
<!DOCTYPE?html> <head> <title>requirejs</title> <meta?charset="utf-8"?/> </head> <body> <div?class="aa">requirejs</div> </body> <script?src="js/require.js"?type="text/javascript"></script> </html>requirejs不使用多個script在html頁面去加載所有js文件,通過require去做我們這種順序加載處理
<script>標簽含有一個特殊的屬性data-main,require.js使用它來啟動腳本加載過程
我們給頁面添加data-main屬性,指定我們的這個主要js控制加載的文件(都是對js的處理,所以省略了.js后綴)
<!DOCTYPE?html> <head> <title>requirejs</title> <meta?charset="utf-8"?/> </head> <body> <div?class="aa">requirejs</div> </body> <script?src="js/require.js"?data-main="js/config.js"?type="text/javascript"></script> </html>和我們的require的路徑一樣,都是放在了js這個文件下面,現在的目錄
requ.html
js/reruire.js
js/config.js
我們已經知道,config.js就是我們的控制文件(文字自定義),在這里面我們定義和處理對其他文件的順序加載
我們給config.js寫入如下代碼
requirejs.config({baseUrl:?'js/modules/',paths:?{jquery:?'jquery'} }); require(['jquery'],?function(jq)?{});我們利用reruirejs的config方法去定義我們依賴的外部文件,
baseUrl屬性:是定義外部文件加載的基本路徑(比如我們的依賴js都在js/modules下)
paths屬性:是定義加載外部文件的文件名,后綴.js省略(名字叫jquery.js,賦給指定鍵名jquery)
require方法:是請求加載我們的外部依賴文件,第一個參數是請求路徑,這里就是jquery類庫(目錄js/modules/jquery.js),
jquery這個鍵值會自動拼接成 baseUrl+paths的路徑進行加載
第二個參數是回調函數,里面的回調參數被賦值為請求的依賴文件
我們先看一下我們下載的目錄結構:
requ.html
js/reruire.js
js/config.js
js/modules
js/modulesjquery.js
我們會把大量的外部放置在modules文件夾下面,html利用requirejs通過script加載外部文件,那么大量文件的基本目錄就是:js/modules
我們瀏覽器打開html頁面,firebug插件頁面結構
我們的html頁面其實只定義了require.js的引用,通過對config上面的設置,我們發現html頁面已經加載了config.js和jqurey.js文件了!
config.js路徑和data-mian的設置一樣,
<script src="js/require.js" data-main="js/config.js" type="text/javascript"></script>
jquery.js的路徑就是我們設置里面的baseUrl+paths
我們可以看出,我們config對路徑的處理是站在html頁面的角度去引用,如果站在config文件的角度去引用就錯了,因為是給html頁面去順序加載js文件的
基本路徑屬性很好理解,就是相對html的路徑,
文件屬性的設置我們需要給他設置一個鍵名,鍵名的后面是引入文件的名字
require()方法:可以通過你的鍵名去請求加載外部文件的,看上面的path設置
我們通過config()定義了依賴文件
現在通過require()得到依賴,并且在回調函數中賦給了回調參數$
我們在回調函數內添加我們的jq處理代碼,config.js修改如下
requirejs.config({?baseUrl:?'js/modules/',??paths:?{????jquery:?'jquery'??} }); require(['jquery'],?function($)?{?alert($(window).height());$("body").append("<div>append</div>") });頁面彈出了窗口高度并且插入了div,我們利用requirejs加載jq類庫,和基于jq的代碼處理就完成了!!!
?
我們可以自己定義模塊,用于依賴加載處理,
我們的依賴文件代碼要放置在define()中。作為模塊的定義,這樣requirejs才可以加載依賴
我們創建自定義依賴文件,叫做ex.js(目錄js/modules/ex.js)
modules創建ex.js,
define(function()?{??var?ex="我是依賴"return?ex;? });config.js設置引入
requirejs.config({?baseUrl:?'js/modules/',??paths:?{????jquery:?'jquery',ex:?'ex'??} }); require(['jquery',"ex"],?function($,ex)?{?alert(ex)});我們瀏覽器打開HTML頁面,會彈出“我是依賴”。
在js文件,我們將定義的內容反之在define里面,我們在config方法設置路徑,require請求到,返回到到回調函數,我們回調函數的參數就會賦值為define里的內容
對于當前的ex.js文件就是在回調函數中 ex=function() {???var ex="我是依賴";?return ex;?}
我們把ex的代碼就行處理,不用原生js的處理代碼,使用jq的代碼,修改如下:
define(function()?{??var?ex=$(window).height();return?ex; });審查報錯了,因為你定義的模塊不知道$是什么,define提供依賴的支持,我們修改如下:
define(["./jquery"],function($)?{??var?ex=$(window).height();return?ex; });和require方法類似,可以先進行依賴請求,然后回調到回調參數中,這樣定義的代碼就對jq識別了,我們可以成功運行
我們看到,define加載依賴的路徑是相對于當前js文件的,
我們既然在定義模塊可以加載依賴,好了把ex.js修改為jq插件的形式,我們在以前文章寫過jq的插件,我們以tab切換為案例
ex.js引入jq類庫依賴,放入插件代碼:
define(["./jquery"],function($)?{??return?$.fn.extend({tab:function(){?return?this.each(function?()?{?var?obj?=?$(this);obj.find(".tabnav").children().click(function(){$(this).addClass("fou").siblings().removeClass("fou");$(this).parent().parent().find(".tabbox").children().eq($(this).index()).show().siblings().hide();});});}}); });我們直接把插件的代碼放入define里面就好了,我們的config.js代碼引用插件
requirejs.config({?baseUrl:?'js/modules/',??paths:?{????jquery:?'jquery',ex:?'ex'??} }); require(['jquery',"ex"],?function($,ex)?{?$(".tab1").tab();?});這時候ex回調參數其實沒有什么意義,因為我們依賴是jq的插件,他會自動加上新的功能,我們html加上tab切換的html代碼
<!DOCTYPE?html> <head> <title>requirejs</title> <meta?charset="utf-8"?/> <style?type="text/css"> /*reset*/ *{?padding:0;?margin:0} body{?height:?100%;?width:?100%;?font-size:12px;?color:#333;} /*demo*/ .tab1{height:400px;?width:400px;} .tabnav{height:50px;?line-height:50px;} .tabnav?span{?cursor:pointer;?margin:0?10px;} .tabnav?.fou{?color:#36F;} .tabbox{height:350px;?} </style> </head> <body> <div?class="tab1"><div?class="tabnav"><span?class="fou">111</span><span>222</span><span>333</span></div><div?class="tabbox"><div>111111</div><div?style="display:none;">22222222222</div><div?style="display:none;">33333333</div></div> </div>? </body> <script?src="js/require.js"?data-main="js/config.js"?type="text/javascript"></script> </html>瀏覽器打開修改的頁面,我們的tab效果成功執行了。
我們的插件里面放置了依賴,其實config里面可以放棄對jq類庫的引用的
config修改如下
requirejs.config({?baseUrl:?'js/modules/',??paths:?{????ex:?'ex'??} }); require(["ex"],?function(ex)?{?$(".tab1").tab();?});還是可以正確執行!插件里面加載了jq類庫,當前沒有加載!
我們如果在外部define定義模塊加載了模塊,那么我們這里引用外部文件會把define定義的代碼和他的依賴都加載進去html頁面
我們通過require加載的依賴,就是把整個js依賴放入在html中,我們config.js如下處理
requirejs.config({?baseUrl:?'js/modules/',??paths:?{????jquery:?'jquery'??} }); require(["jquery"],?function()?{?alert($(window).height())});我們的jq一樣有效,請求到后,那么在回調內部就可以進行處理!
我們創建一個完整的項目,結構如下
requ.html?? ?我們的靜態頁面
js/reruire.js??? ?require文件
js/config.js???? ?主要配置文件
js/modules??? ?存放jq類庫和插件文件的文件夾
js/modules/jquery.js????? jq類庫
js/handle/ys.js??原生js文件,匿名函數返回消息
js/handle/ysfun.js ?原生js文件,匿名函數返回工具函數
html頁面代碼:
<!DOCTYPE?html> <head> <title>requirejs</title> <meta?charset="utf-8"?/> <style?type="text/css"> /*reset*/ *{?padding:0;?margin:0} body{?height:?100%;?width:?100%;?font-size:12px;?color:#333;} /*demo*/ .tab1{height:400px;?width:400px;} .tabnav{height:50px;?line-height:50px;} .tabnav?span{?cursor:pointer;?margin:0?10px;} .tabnav?.fou{?color:#36F;} .tabbox{height:350px;?} </style> </head> <body> <div?class="tab1"><div?class="tabnav"><span?class="fou">111</span><span>222</span><span>333</span></div><div?class="tabbox"><div>111111</div><div?style="display:none;">22222222222</div><div?style="display:none;">33333333</div></div> </div>? </body> <script?src="js/require.js"?data-main="js/config.js"?type="text/javascript"></script> </html>ex.js代碼:
define(["./jquery"],function($)?{??return?$.fn.extend({tab:function(){?return?this.each(function?()?{?var?obj?=?$(this);obj.find(".tabnav").children().click(function(){$(this).addClass("fou").siblings().removeClass("fou");$(this).parent().parent().find(".tabbox").children().eq($(this).index()).show().siblings().hide();});});}}); });ys.js代碼:
define(function()?{??var?ys="我是就是一個消息!";return?ys; });ysfun.js代碼:
define(function()?{??var?tools={};tools.norepeat=function(arr){arr.sort();var?newarr=[];for(var?i=0;i<arr.length;i++){??if(arr[i]==arr[i+1]){continue;}else{newarr.push(arr[i]);}};return?newarr;};tools.strindex=function(str,arr){var?index;for(var?i=0;i<arr.length;i++){if(arr[i]==str){index=i;}};return?index;};return?tools; });config.js代碼:
requirejs.config({?baseUrl:?'js',??paths:?{????jquery:?'modules/jquery',ex:?'modules/ex',?ys:?'handle/ys'?,ysfun:?'handle/ysfun'?} }); require(["jquery","ex","ys","ysfun"],?function($,ex,ys,ysfun)?{?$(".tab1").tab();?alert(ys);var?arr1=["123","44","55","66","789","44"];alert(ysfun.norepeat(arr1));alert(ysfun.strindex("66",arr1));});頁面依賴jq類庫,依賴jq的插件,還有其他js處理,一個基本頁面的js引用大概就這些!
?大概的實現:
define定義模塊,
config設置依賴
require請求加載依賴,回到參數可以接收依賴返回內容,回調函數內做進一步處理
?Commonjs規范在nodejs有體現,我們看看利用nodejs建站就知道了!
?
?
?
?
轉載于:https://my.oschina.net/tbd/blog/494404
總結
以上是生活随笔為你收集整理的JS三教九流系列-require.js-网站模块化开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 乐视云没创意,还拿“免费”说事儿
- 下一篇: 论如何优雅的处理回文串 - 回文自动机详