seajs快速參考
該頁(yè)面列舉了 SeaJS 中的常用 API。只要掌握這些方法,就可以嫻熟地進(jìn)行模塊化開(kāi)發(fā)。
啟動(dòng)模塊系統(tǒng)
<script src="http://modules./seajs/1.2.0/sea.js"></script>
<script>
seajs.use('./main');
seajs.use(['./a', './b'], function(a, b) {
a.init();
b.init();
});
</script>
//callback 參數(shù)是可選的。當(dāng)只啟動(dòng)加載一個(gè)模塊,且不需要 callback 時(shí),可以用 data-main 屬性來(lái)簡(jiǎn)化:
<script src="http://modules./seajs/1.2.0/sea.js" data-main="./main"></script>
/*
引入 sea.js 時(shí),可以把 sea.js 與其他文件打包在一起,提前打包好,或利用 combo 服務(wù)動(dòng)態(tài)打包。
無(wú)論哪一種方式,為了讓 sea.js 內(nèi)部能快速獲取到自身路徑,推薦手動(dòng)加上 id 屬性:
加上 seajsnode 值,可以讓 sea.js 直接獲取到自身路徑,而不需要通過(guò)其他機(jī)制去自動(dòng)獲取。
這對(duì)性能和穩(wěn)定性會(huì)有一定提升,推薦默認(rèn)都加上。
*/
<script src="path/to/sea.js" id="seajsnode"></script>
seajs.config
//seajs.config 可以疊加,可以在多處調(diào)用,同名 key 覆蓋,不同名的 key 疊加。這樣可以做到:區(qū)域配置可以覆蓋通用配置或可以說(shuō)在區(qū)域配置中可對(duì) seajs config 再做按需配置而不會(huì)影響到通用配置。
seajs.config({
//alias最常用來(lái)做版本配置與管理,也可以用來(lái)做命名空間管理。
alias: {
'es5-safe': 'es5-safe/0.9.2/es5-safe',
'json': 'json/1.0.1/json',
'jquery': 'jquery/1.7.2/jquery'
},
/*
使用 preload 配置項(xiàng),可以在普通模塊加載前,提前加載并初始化好指定模塊。
注意:preload 中的配置,需要等到 use 時(shí)才加載。
preload 配置不能放在模塊文件里面
*/
preload: [
Function.prototype.bind ? '' : 'es5-safe',
this.JSON ? '' : 'json'
],
//值為 true 時(shí),加載器會(huì)使用 console.log 輸出所有錯(cuò)誤和調(diào)試信息。 默認(rèn)為 false, 只輸出關(guān)鍵信息
debug: true,
//該配置可將某個(gè)文件映射到另一個(gè)。可用于在線調(diào)試,非常方便。
map: [
['http:///js/app/', 'http://localhost/js/app/']
],
/*
SeaJS 在解析頂級(jí)標(biāo)識(shí)時(shí),會(huì)相對(duì) base 路徑來(lái)解析。
注意:一般請(qǐng)不要配置 base 路徑,保持默認(rèn)往往最好最方便。
base 路徑的默認(rèn)值,與 sea.js 的訪問(wèn)路徑相關(guān):
如果 sea.js 的訪問(wèn)路徑是:
http:///js/libs/sea.js
則 默認(rèn)base 路徑為:
http:///js/libs/
*/
base: 'http:///path/to/base/',
//獲取模塊文件時(shí),<script> 或 <link> 標(biāo)簽的 charset 屬性。 默認(rèn)是 utf-8 。
charset: 'utf-8'
});
seajs.use
/*
模塊加載器
seajs.use 理論上只用于加載啟動(dòng),不應(yīng)該出現(xiàn)在 define 中的模塊代碼里。在模塊代碼里需要異步加載其他模塊時(shí),可以使用 require.async 方法。
*/
seajs.use('./a');
seajs.use('./a', function(a) {
a.doSomething();
});
seajs.use(['./a', './b'], function(a, b) {
a.doSomething();
b.doSomething();
});
//seajs.use 與 dom ready 事件沒(méi)有任何關(guān)系。
//如果某些操作要確保在 dom ready 后執(zhí)行,需要自己使用 jquery 等類(lèi)庫(kù)來(lái)保證
seajs.use(['jquery', 'page'], function($, page) {
$(function() {
page.init()
})
})
define
/*
CMD 模塊定義 define(factory);
define 是全局函數(shù),用來(lái)定義模塊。
在開(kāi)發(fā)時(shí),define 僅接收一個(gè) factory 參數(shù)。
factory 可以是一個(gè)函數(shù),也可以是對(duì)象、字符串等類(lèi)型。
factory 為對(duì)象、字符串等非函數(shù)類(lèi)型時(shí),表示模塊的接口就是該對(duì)象、字符串等值。
factory 為函數(shù)時(shí),表示模塊的構(gòu)造方法。執(zhí)行該方法,可以得到模塊向外提供的接口。
*/
define(function(require, exports, module) {
// The module code goes here
});
/*
模塊代碼需要用 define 回調(diào)包起來(lái):id 與 dependencies 參數(shù)是可以省略的
id 用來(lái)顯式指定模塊 ID。當(dāng)你的項(xiàng)目上線,所有的模塊都合并到了一個(gè)文件中,如果不顯示指定, SeaJS 就無(wú)從知道哪個(gè)模塊是哪個(gè)了。在開(kāi)發(fā)的時(shí)候,一般用不到它。
dependencies 也是如此。它列出了當(dāng)前模塊所依賴的模塊,在開(kāi)發(fā)的時(shí)候是不需要寫(xiě)明的。 SeaJS 會(huì)檢查你的模塊回調(diào)函數(shù),找到所有的 require 語(yǔ)句,從而得到你的模塊的所有依賴。 在真正 require 當(dāng)前模塊時(shí),會(huì)先去請(qǐng)求這個(gè)模塊的依賴,加載完畢,再去初始化當(dāng)前的模塊。
*/
define(id, dependencies, function(require, exports, module) {
// module code.
});
require
/*
require 是一個(gè)方法,用來(lái)獲取其他模塊提供的接口。
require 接受 模塊標(biāo)識(shí) 作為唯一參數(shù)
模塊依賴解析,靠的是三個(gè)重要的規(guī)則:
不能重命名 require
不能覆蓋 require
require 的參數(shù)必須是字符串字面量,不可以 require(foo()) 或者 require(bar), 也不可以是 require(should_be_a ? 'a' : 'b')。 參數(shù)值必須是字符串直接量,如 require("my-module");
核心原因是因?yàn)樵跒g覽器端,文件的讀取是異步的,依賴信息要提前獲取,不能在運(yùn)行時(shí)才確定。在服務(wù)器端,文件讀取是同步的,因此可以是變量。
*/
define(function(require) {
var a = require('./a');
a.doSomething();
});
require.async
/*
require.async(id, callback)
async 方法可用來(lái)異步加載模塊,并在加載完成后執(zhí)行指定回調(diào)。
*/
define(function(require, exports, module) {
// load one module
require.async('./b', function(b) {
b.doSomething();
});
// load multiple modules
require.async(['./c', './d'], function(c, d) {
// do something
});
});
require.resolve
/*
require.resolve(id)
使用模塊系統(tǒng)內(nèi)部的路徑解析機(jī)制來(lái)解析并返回模塊路徑。該函數(shù)不會(huì)加載模塊,只返回解析后的絕對(duì)路徑。
*/
define(function(require, exports) {
console.log(require.resolve('./b'));
// ==> 'http:///js/b.js'
});
exports
/*
exports 是一個(gè)對(duì)象,用來(lái)向外提供模塊接口。
exports 僅僅是 module.exports 的一個(gè)引用。
在 factory 內(nèi)部給 exports 重新賦值時(shí),并不會(huì)改變 module.exports 的值。
因此給 exports 賦值是無(wú)效的,不能用來(lái)更改模塊接口,正確的寫(xiě)法是用 return 或者給 module.exports 賦值。
exports = {}是錯(cuò)誤的,module.exports ={}才是正確的寫(xiě)法。
*/
define(function(require, exports) {
// snip...
exports.foo = 'bar';
exports.doSomething = function() {};
});
module.exports
define(function(require, exports, module) {
// snip...
module.exports = {
name: 'a',
doSomething: function() {};
};
});
module
/*
module 是一個(gè)對(duì)象,上面存儲(chǔ)了與當(dāng)前模塊相關(guān)聯(lián)的一些屬性和方法。
*/
define(function(require, exports, module) {
//module.id 模塊標(biāo)識(shí)。require(module.id) 必然返回此模塊的 exports 。
console.log(require(module.id) === exports); // true
//module.uri根據(jù)模塊系統(tǒng)的路徑解析規(guī)則得到的模塊絕對(duì)路徑。
console.log(module.uri); // http:///path/to/this/file.js
//module.dependencies dependencies 是一個(gè)數(shù)組,表示當(dāng)前模塊的依賴列表。
/*
module.exports 當(dāng)前模塊對(duì)外提供的接口。
module.exports 的賦值需要同步執(zhí)行,不能放在回調(diào)函數(shù)里
*/
});
以上接口是最常用的,要牢記于心。
可寫(xiě)成如下
seajs.config({
alias: {
'jquery': 'http://modules./jquery/1.7.2/jquery.js'
}
});
define('hi', function(require, exports) {
exports.sayHi = function() {
alert('hi')
}
})
seajs.use(['jquery', 'hi'], function($, h) {
$('#beautiful-sea').click(h.sayHi)
});
模塊化后的js寫(xiě)法
define(function(require, exports, module) = {
//原jquery.js代碼...
module.exports = $.noConflict(true);
});
//init.js
define(function(require, exports, module) = {
var $ = require('jquery');
var m1 = require('module1');
exports.initPage = function() {
$('.content').html(m1.run());
}
});
//module1.js
define(function(require, exports, module) = {
var $ = require('jquery');
var m2 = require('module2');
var m3 = require('module3');
exports.run = function() {
return $.merge(['module1'], $.merge(m2.run(), m3.run()));
}
});
//module2.js
define(function(require, exports, module) = {
exports.run = function() {
return ['module2'];
}
});
//module3.js
define(function(require, exports, module) = {
var $ = require('jquery');
var m4 = require('module4');
exports.run = function() {
return $.merge(['module3'], m4.run());
}
});
//module4.js
define(function(require, exports, module) = {
exports.run = function() {
return ['module4'];
}
});
實(shí)際使用中
在工程內(nèi)使用seajs,以前引用的插件、模塊也都要用define的語(yǔ)法重新進(jìn)行封裝,比較麻煩,老代碼可以不修改,繼續(xù)使用就好。但強(qiáng)烈建立花點(diǎn)時(shí)間都修改成 CMD 模塊,這樣對(duì)以后的維護(hù),以及頁(yè)面性能很有好處。不然以后修改起來(lái)估計(jì)會(huì)更麻煩。
其實(shí)可以混用的,比如:
<script src="jquery.js"></script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
<script src="sea.js"></script>
這樣,常用的 jquery 等類(lèi)庫(kù),依舊是傳統(tǒng)的用法,用全局變量引用就好,通過(guò)同步引入的方式,也不會(huì)有依賴順序問(wèn)題。 自己的代碼,都按照 CMD 規(guī)范寫(xiě)成模塊的形式。
其實(shí)上面的方式挺好的,特別對(duì)于要兼容老代碼的情況的。 推薦還是都徹底模塊化,看起來(lái)要多寫(xiě)一些 require,但值得,因?yàn)檫@樣可以讓每個(gè)模塊自身的信息完整,從而減少對(duì) 環(huán)境的依賴,對(duì)后續(xù)的可維護(hù)性很好益處。
seajs官方api
第三方庫(kù)
SeaJS 提供了一個(gè)類(lèi)似于npm的管理工具,里面有他們改造好的第三方庫(kù),你可以在這里找找是否有適合的:
seajs blog 等文檔
初級(jí)入門(mén)
中級(jí)使用
高級(jí)探索
|