前端進階課程之模組化(二)AMD規範

沉默抒懷者發表於2018-11-23

一:require.js

疑問:為什麼會出現AMD規範呢?為什麼會出現require.js呢?解決了什麼問題?

答案:在沒有AMD規範之前,我們是採用Commonjs規範,但是Commonjs規範是同步載入模組,它是node普通採用的一種模組機制,對於node而言,常見的載入本地檔案或者其他各種I/O操作,速度是很快的,我們採用同步機制去載入模組檔案是沒有問題的,但是對於瀏覽器端而言,請求網路資源的速度是很慢的,如果依然採用同步方式去請求資源,瀏覽器端很可能造成阻塞問題,

所以,解決方法是什麼呢?AMD(Asynchronous Module Definition) 非同步模組定義 而require.js是AMD規範的具體實現。

例如:如下程式碼,

我們希望在index.html,引入main.js, a.js, b.js, c.js四個js檔案

第一種:最原始的做法,在index.html裡面,從上到下同步載入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="./lib/a.js"></script>
<script src="./lib/b.js"></script>
<script src="./lib/c.js"></script>
<script src="./lib/main.js"></script>
</body>
</html>
問題:這樣只能從上到下,同步載入js檔案,可能由於前面的js檔案過大,造成阻塞問題
複製程式碼

第二種:採用require.js來非同步載入js檔案

//index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
//data-main去宣告主入口檔案
<script src="./require.js" data-main="./main.js"></script>
</body>
</html>
//main.js
//寫法1:直接引入js檔案
require(['./a', './b', './c'], function () {
   console.log('檔案全部載入成功');
});
//寫法2:設定js檔案別名
require.config({
    paths: {
        aaa: './lib/a',
        bbb: './lib/b',
        ccc: './lib/c'
    }
});
或者
require.config({
    baseUrl: './lib',
    paths: {
        aaa: 'a',
        bbb: 'b',
        ccc: 'c'
    }
});

require(['aaa', 'bbb', 'ccc'], function () {
    console.log('檔案全部載入成功');
});
複製程式碼

二:AMD與require.js的關係

通過上面,可以知道:

AMD是一種規範,而require.js是真正的實現,主要解決了兩個問題:

1:實現js檔案的非同步載入,避免同步載入導致的網頁阻塞

2: 定義模組之間如何相互依賴,可以更好的管理模組。

三:AMD規範程式碼例項

//index.html : 引入require.js,確定主入口檔案main.js
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="./require.js" data-main="./main.js"></script>
</body>
說明:data-main屬性用於說明require.js載入的模組主入口是什麼。
複製程式碼
//在main.js中引入a.js模組:
require.config({
    baseUrl: './lib',
    paths: {
        aaa: 'a',
    }
});
require(['aaa'], function (a) {
    console.log(a);//此處,在回撥方法中,就可以獲取define中定義的物件:{name: '111'}
});

複製程式碼
//a.js: 使用define方法直接傳入一個物件,或者傳入一個函式,函式返回一個物件
define({
    name: '111'
});

複製程式碼

相關文章