require.js 載入過程與使用方法
require.js簡介
require.js是javascript模組化程式設計中常用的一個JS庫。
現在的網頁功能較以前已經豐富了許多,同時網頁上需要匯入越來越多的JS檔案來實現這些功能。使用原有的script標籤一個個匯入js檔案會導致程式碼的複雜與臃腫。並且匯入的各個JS檔案可能會有衝突,導致許多功能無法使用且會使bug非常難定位。
這樣的情況下我們就需要一個合適的Javascript模組載入框架,來滿足我們團隊協作、模組複用、單元測試等等一系列複雜的需求。使用require.js進行模組化載入會使前端程式碼的質量得到提升。
require.js的優點
- 不使用require.js的寫法
在以前的程式設計中,我們或許會這樣匯入js檔案:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="xxx.js"></script>
</head>
<body>
<span>body</span>
</body>
</html>
而在xxx.js檔案中我們會這樣寫:
function fun1(){ alert("it works"); } fun1();
上述的xxx.js檔案中的fun1方法可能會與其他檔案中的方法重名導致方法被過載覆蓋,會導致一些未知的bug。所以一些有經驗的程式設計師或許會更傾向與這樣寫:
(function(){
function fun1(){
alert("it works");
}
fun1();
})()
這樣編碼的好處在於限制了fun1方法的作用域,這樣就不會被其他的fun1方法所重寫。並且這樣的寫法也防止了汙染全域性變數。
我們執行以上的程式碼時,會發現xxx.js中的alert執行時,頁面並未載入完成。(body標籤中的span並未顯示在頁面中)。這是因為alert阻塞了瀏覽器渲染,等alert完成後瀏覽器才會繼續進行渲染。(這裡很像主程序被阻塞了,程式會等待當前操作完成後再繼續進行)。- 使用require.js
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="require.js"></script>
<script type="text/javascript">
require(["a"]);
</script>
</head>
<body>
<span>body</span>
</body>
</html>
這裡先匯入了require.js,然後使用require([“xxx”])來載入xxx.JS檔案
xxx.js
define(function(){
function fun1(){
alert("it works");
}
fun1();
})
執行上兩個檔案,我們發現alert時並未阻塞瀏覽器渲染,body中的span依然出現在了頁面上。所以首先我們可以發現,使用require.js進行載入時我們不會阻塞瀏覽器渲染。
同時,我們會發現使用require.js載入時,也是完全避免了js檔案中的方法被重寫覆蓋或js檔案中的變數、方法汙染全域性變數、方法的情況。
我們使用程式程式碼載入模組,也避免了下面這樣醜陋的情況:
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b.js"></script>
<script type="text/javascript" src="c.js"></script>
<script type="text/javascript" src="d.js"></script>
<script type="text/javascript" src="e.js"></script>
<script type="text/javascript" src="f.js"></script>
<script type="text/javascript" src="g.js"></script>
<script type="text/javascript" src="h.js"></script>
<script type="text/javascript" src="i.js"></script>
<script type="text/javascript" src="j.js"></script>
require.js 的載入
使用require.js非同步載入js檔案時,相當於是另開一個執行緒來進行載入檔案這個操作。在require.js的定義中,我們可以在要載入的檔案中新增它的依賴項,這些依賴檔案會該檔案被載入之前先載入,再以引數的方式傳入到該檔案之中。
xxx.js寫法如下:
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
// some code here
});
此時xxx.js依賴於moduleA,moduleB,moduleC。 使用require.js載入xxx.js時,會先載入moduleA,moduleB,moduleC三個模組,然後以引數的方式傳入xxx.js中。
這裡我們原則上要避免迴圈依賴的出現。例如:A依賴與B,B又依賴與A。這樣就出現了迴圈依賴。
雖然出現迴圈依賴不會導致載入失敗,但是在載入A時,傳入A的依賴項B中的A引數會為null值,導致一些無法預知的問題。所以我們還是要儘量避免迴圈依賴的情況出現。
這裡的非同步載入都不會影響該檔案以外的所有變數與方法。