seajs遵循CMD規范,requirejs遵循AMD規范。AMD規范是預加載,CMD規范是賴加載。
下文舉例假設有文件 b.js, c.js如下
//b.js define(function(require, exports, module){ console.log('b is loaded') function run(){ console.log('b run'); } exports.run = run; }) //c.js define(function(require, exports, module){ console.log('c is loaded') function run(){ console.log('c run'); } exports.run = run; })
1. seajs對依賴模塊只加載不執行,requirejs對依賴模塊既加載也執行
運行代碼:
// seajs <!DOCTYPE html> <html> <head> <title>seajs</title> <script type="text/javascript" src="./sea.min.js"></script> </head> <body>
<button id="btn">OK</button>
<script type="text/javascript"> seajs.use('./a.js') </script> </body> </html> // requirejs <!DOCTYPE html> <html> <head> <title>requirejs</title> <script type="text/javascript" src="./require.js"></script> </head> <body>
<button id="btn">OK</button>
<script type="text/javascript"> require(['a']) </script> </body> </html> // a.js define(['b'], function(){ })
運行結果:
seajs:
控制台無輸出
requirejs:
控制台:
2. seajs ,requirejs在 require文件時既加載也執行
//a.js define(function(require, exports, module){ var b = require('b') })
requirejs:
控制台:b is loaded
seajs:
控制台:b is loaded
3. seajs可以在任意處直接require文件,無需提前寫依賴模塊;一旦提前寫了任意一個依賴模塊,下面的所有require的使用必須保證也有其對應的依賴模塊
seajs可以直接如下使用,無需寫依賴['b']:
//a.js
define(function(require, exports, module){ var b = require('b') })
或
define(['b'], function(require, exports, module){
var b = require('b') })
運行結果:
控制台:b is loaded
假如 a.js 依賴了另一個 c.js,則在 a.js 中使用 require('b') 時必須也寫上依賴['b'],否則b.js將因為查找不到而不會加載
define(['c'], function(require, exports, module){ var b = require('b') })
運行結果:
控制台無輸出(不會輸出c is loaded, 因為沒有require('c') )
如果此時我們執行b.run()
define(['c'], function(require, exports, module){ var b = require('b') b.run() })
控制台將會報錯,因為此時b為null:
此時正確寫法應該寫上依賴 ['b']:
define(['c', 'b'], function(require, exports, module){ var b = require('b') b.run() })
運行結果:
結論:
對於seajs,如果不寫依賴那就一個都不要寫,一旦寫了,下面所有require的地方都需要提前在頭部寫上依賴
但對require.ascnc例外,可以如下寫法:
//a.js
define(['c'], function(require, exports, module){ var b = require.async('b'); })
此時c.js, b.js都被加載,只有 b.js 被執行
下一點將會介紹require.async
requirejs的依賴寫法如下:
define(['c', 'b'], function(c, b){ var b = require('b') b.run() }) 或 define(function(require, exports, module){ var b = require('b') b.run() }) //錯誤寫法 define(['c'], function(c){ var b = require('b') b.run() })
4. seajs的require.async在執行到使用位置的時候才去異步加載
seajs:
如下例:
// a.js define(function(require, exports, module){ document.getElementById('btn').addEventListener('click', function(){
document.getElementById('btn').innerHTML = 'btn is clicked' init() }) function init(){ var b = require('b'); b.run() } })
運行結果:
控制台無輸出
點擊OK按鈕, b.js 加載並執行b.js和run方法:
大家注意到,在未點擊按鈕之前,雖然沒有執行init方法,但b.js依然被提前加載了進來,但沒有被執行(沒有輸出b is loaded)。
很多時候我們想在執行init方法的時候再去加載b.js,而不是提前在頁面加載的時候就把b,js加載。
這時候就需要用到require.async,如下:
//a.js define(function(require, exports, module){ document.getElementById('btn').addEventListener('click', function(){ document.getElementById('btn').innerHTML = 'btn is clicked' init() }) function init(){ require.async('b', function(b){ b.run() }); } })
這時候運行結果:
b.js沒有被加載:
控制台無輸出:
點擊OK按鈕:
b.js被加載
控制台輸出:
這是因為當執行一個js時,seajs會先去查找匹配require,然后加載相應資源,但不執行。匹配到require.async時不加載。
所以,require.async達到了用到時再去異步加載並執行的目的。
小問題:
如果是requirejs執行下面代碼:
//a.js define(function(require, exports, module){ document.getElementById('btn').addEventListener('click', function(){ document.getElementById('btn').innerHTML = 'btn is clicked' init() }) function init(){ var b = require('b'); b.run() } })
資源如何加載?控制台又會輸出什么呢?點擊ok按鈕又會輸出啥?
答:資源加載了a.js, b.js, 控制台輸出:b is loaded, 點擊OK按鈕控制台繼續輸出:b run
(選擇“答”后面的部分查看答案)
總結:
1. seajs對依賴模塊只加載不執行,requirejs對依賴模塊加載並執行 2. seajs ,requirejs在 require具體文件時既加載也執行 3. seajs可以在任意處直接require文件,無需提前寫依賴模塊;一旦提前寫了任意一個依賴模塊,下面的所有require的使用必須保證也有其對應的依賴模塊 4. seajs的require.async在執行到使用位置的時候才去異步加載
本文demo:
https://github.com/saysmy/seajs-requirejs-demo