下載
在cmd命令窗口通過npm install saejs下載
seajs的npm下載指令查找方法如下
下載完成後,生成一個node_modules目錄,seajs核心文件放在node_modules\seajs\dist下,如下圖所示
引入seajs
新建index.html文件,將sea.js和index.html放在同一級目錄
在index.html中通過script標籤引入sea.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 引入sea.js -->
<script type="text/javascript" src="./sea.js"></script>
<script type="text/javascript">
console.log(seajs)
</script>
</body>
</html>
seajs向外暴露了一個變量seajs,在上面代碼中輸出seajs
從控制枱的輸出可以看到,seajs是一個對象,有很多屬性和方法,我們對其的配置,就是調用了裏面的config()方法
config方法的源碼
seajs.config = function(configData) {
for (var key in configData) {
var curr = configData[key]
var prev = data[key]
// Merge object config such as alias, vars
if (prev && isObject(prev)) {
for (var k in curr) {
prev[k] = curr[k]
}
}
else {
// Concat array config such as map
if (isArray(prev)) {
curr = prev.concat(curr)
}
// Make sure that `data.base` is an absolute path
else if (key === "base") {
// Make sure end with "/"
if (curr.slice(-1) !== "/") {
curr += "/"
}
curr = addBase(curr)
}
// Set config
data[key] = curr
}
}
emit("config", configData)
return seajs
}
從config方法的源碼for (var key in configData)可知,config()方法的參數應該是一個對象,每一種配置項是一個屬性(key:value,key是配置名稱,value是配置結果),遍歷config()方法的參數,並將每種配置的名稱和結果放在seajs.data(也是一個對象)裏面
標識符
seajs模塊標識分為3種:相對標識、頂級標識和普通標識。
相對路徑,以. 或 ..開頭
頂級路徑,不以.或 ..及斜線(/)開頭
普通路徑,除相對和頂級路徑外的,比如/(根路徑)開頭的,"http://"、"https://"、"file:///" 等協議標識開頭的
模塊命名空間是seajs所在文件的根路徑即所謂的base路徑,去除了seajs/x.y.z 字串,也可以指定seajs.config({base:});
base配置
base配置項在不設置時,表示的是sea.js文件位置,因為seajs的配置結果存放在seajs.data中,在控制枱輸出seajs.data
本地電腦上sea.js文件位置
證明base就是sea.js文件所在的路徑
在main.js中定義一個模塊,並向外暴露
//main.js
// 定義一個沒有ID的模塊
define(function(require,exports,module){
// 向外暴露
module.exports.name = '張三'
})
在index.html文件中使用seajs.use()方法引入入口模塊文件main.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 引入sea.js -->
<script type="text/javascript" src="./sea.js"></script>
<script type="text/javascript">
//引入入口模塊
seajs.use('main',function(a){
console.log(a) //a為引入的入口文件內的模塊向外暴露的對象
console.log('入口模塊引入完畢')
})
</script>
</body>
</html>
注意看seajs.use()方法裏面的第一個參數,"main"乍一看好像沒問題,mian.js不就是和index.html在同一級目錄嗎,其實不然,這是頂級路徑(不以.、..、/開頭,直接以文件名或者文件夾名開頭),是相對於sea.js的路徑而言的,只是剛好這裏sea.js和index.html在同一級目錄,所以看起來像是相對於index.html,如果寫成./main才是相對於index.html的路徑而言
那我們嘗試更改一下sea.js的位置,將sea.js放在和index.html同級目錄的module文件夾下(E:\SeajsTest\module\),將main.js放在和index.html同級目錄的module文件夾下的main文件夾中
因為sea.js和main.js的位置變了,此時sea.js的路徑是E:\SeajsTest\module\seajs,引入sea.js後在控制枱輸出seajs.data驗證
此時引入main.js時,如果使用頂級路徑應該是main/main,或者寫相對路徑----./module/main/main,表示相對於index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 引入sea.js -->
<script type="text/javascript" src="./module/sea.js"></script>
<script type="text/javascript">
//引入入口模塊
// 1、使用頂級標識符
seajs.use('main/main',function(a){
// 2、使用相對標識符
// seajs.use('./module/main/main',function(a){
console.log(a)
console.log('入口模塊引入完畢')
})
</script>
</body>
</html>
控制枱輸出
修改默認base
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 引入sea.js -->
<script type="text/javascript" src="./module/sea.js"></script>
<script type="text/javascript">
// 修改base
seajs.config({
base:'main/' //base:"./main"寫法是錯誤,因為也遵循seajs標識符的規則,./main/表示和index.html同級的main目錄下
})
//引入入口模塊
// 1、使用頂級標識符
seajs.use('main',function(a){
// 2、使用相對標識符
// seajs.use('./module/main/main',function(a){
console.log(a)
console.log('入口模塊引入完畢')
})
</script>
</body>
</html>
如上所示,我將base修改為main/表示和sea.js同級的main目錄下,即E:\SeajsTest\module\main,此處不能使用base:./main/,因為加上./就表示相對於index.html了,從下圖中控制枱輸出的路徑就可以看出來
alias(別名)配置
當模塊標識很長,寫起來不方便、容易出錯的時候,可以使用alias來簡化模塊標識;還有一種情況當,我們引入一些基礎庫時,經常會涉及到版本升級(版本號發生改變),此時在每個模塊中修改版本號比較麻煩,如果使用alias定義這個模塊,只需在seajs的alias中修改一次即可。在seajs.config中進行一次配置之後,所有js模塊都可以用require("jquery")這種簡單的方式來加載對應的模塊了。使用alias,可以讓文件的真實路徑與模塊調用標識分開,有利於統一維文件目錄如下
│ index.html
│ main.js
│ sea.js
└─ module
├─Jquery
│ Jquery1.12.4.js
我在index.html中引入入口文件mian.js,然後在main.js中引入Jquery1.12.4.js
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 引入sea.js -->
<script type="text/javascript" src="./sea.js"></script>
<script type="text/javascript">
//引入入口文件
seajs.use('main',function(a){
console.log(a);
console.log('入口文件加載完畢')
})
</script>
</body>
</html>
//main.js
// 定義一個沒有ID的模塊
define(function(require,exports,module){
//在入口模塊中引入其他模塊
var jq = require('module/Jquery/Jquery1.12.4')
// 向外暴露
module.exports.name = '張三';
module.exports.JQ = jq;
})
上面的寫法是我們沒有配置alias時的寫法,我現在覺得這個Jquery1.12.4.js的標識符太長,寫起來太麻煩,此時就可以設置別名,注意這裏的別名是針對某個文件(模塊)的標識符,所以alias的值要帶上路徑(不是隻給文件名設置別名)而且精確到文件,同樣的,別名的設置也遵循seajs標識符規則
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 引入sea.js -->
<script type="text/javascript" src="./sea.js"></script>
<script type="text/javascript">
// 配置seajs
seajs.config({
alias:{
//頂級標識符寫法
'JQ':"module/Jquery/Jquery1.12.4",
// 相對標識符寫法
// 'JQ':"./module/Jquery/Jquery1.12.4"
}
})
//引入入口文件
seajs.use('main',function(a){
console.log(a);
console.log('入口文件加載完畢')
})
</script>
</body>
</html>
//main.js
// 定義一個沒有ID的模塊
define(function(require,exports,module){
//在入口模塊中引入其他模塊
// 未配置alias時引入
// var jq = require('module/Jquery/Jquery1.12.4')
//配置alias後引入
var jq = require('JQ')
//上面的`JQ`是頂級標識符,等於base的值加上別名JQ代表的模塊路徑
// 向外暴露
module.exports.name = '張三';
module.exports.JQ = jq;
})
這樣一設置,寫起來就簡單多了,而且一次設置,所以地方都可以用
paths(路徑)配置
當目錄層次比較深,或者是跨目錄調用模塊的時候,可以用path簡化模塊標識的書寫,path與alias不同的是,path針對的是某個文件夾。paths 配置可以結合 alias 配置一起使用,讓模塊引用非常方便。文件目錄如下
│ index.html
│ main.js
│ sea.js
│
└─module
└─one
└─two
└─three
A.js
B.js
還是老規矩,index.html中引入入口模文件塊main.js,然後在main.js中在引入A.js和B.js,index.html內容還和上面一樣,下面是main.js的代碼
//main.js
// 定義一個沒有ID的模塊
define(function(require,exports,module){
//在入口模塊中引入其他模塊
var moduleA = require('module/one/two/three/A.js')
var moduleB = require('module/one/two/three/B.js')
module.exports.person = moduleA;
module.exports.studemt = moduleB;
})
可以看到A.js和B.js文件位置相對於sea.js和index.html很深,所以在main.js中引入時路徑很長,當要引入three文件夾下更多模塊文件時,寫起來很麻煩,這個是時候paths就派上用場了,其實跟alias有點像,可以看做是給某個文件夾設置了別名
// 定義一個沒有ID的模塊
define(function(require,exports,module){
//在入口模塊中引入其他模塊
// 1、不配置paths時的寫法
// var moduleA = require('module/one/two/three/A.js')
// var moduleB = require('module/one/two/three/B.js')
//2、配置paths後的寫法
var moduleA = require('three/A.js');
var moduleB = require('three/B.js');
module.exports.person = moduleA;
module.exports.studemt = moduleB;
})
要是需要引入的模塊在同一文件夾下,而且藏得又深名字還長,那麼就使用alias和paths配合使用,給文件設置alias(別名),給文件夾設置paths(路徑)
vars(變量)配置
目錄如下
│ index.html
│ main.js
│ sea.js
│
└─module
└─language
en.js
zh-cn.js
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- 引入seajs -->
<script src="./sea.js"></script>
<!-- 引入入口模塊文件 -->
<script>
// 配置seajs
seajs.config({
vars:{
cn:"zh-cn"
}
})
// 使用seajs.use()方法引入入口模塊
seajs.use('main',function(a){
console.log('入口模塊加載完畢')
// 輸出入口模塊向外暴露的對象
console.log(a);
})
</script>
</body>
</html>
//main.js
// 定義入口模塊
define(function(require,exports,module){
// 引入其他模塊
// 未配置vars時的寫法
// var language = require('module/language/zh-cn')
// 配置vars後的寫法
var language = require('module/language/{cn}')
module.exports.language = language;
})
vars是一個對象,對象內有kv鍵值對,k是一個變量,用於代替v,在引入模塊文件時,可以使用{}包裹k的形式來代替v,形如{K},有點像插值語法,官網説是動態加載,看了很多文章都是引用官網的例子,哎,我也不知道什麼場景下使用,我感覺和alias真的一樣
map(映射) 配置
map用於對模塊路徑進行映射修改,可用於路徑轉換,在線調試等文件目錄如下
index.html
│ main.js
│ sea.js
│
└─module
debug.js
runtime.js
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- 引入seajs -->
<script src="./sea.js"></script>
<script>
// 配置seajs
seajs.config({
map:[
['runtime.js','debug.js']
]
})
// 引入入口模塊
seajs.use('main',function(a){
console.log('入口模塊加載完畢')
console.log(a)
})
</script>
</body>
</html>
// 定義入口模塊
define(function(require,exports,module){
// 引入其他模塊
var M = require('module/runtime')
module.exports.state = M;
})
上面的例子模擬了類似測試時的場景,將模塊路徑進行了轉換
參考文章01
參考文章02
參考文章03
參考文章04
參考文章05