下载
在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
Document
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
Document
注意看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
Document
控制台输出
修改默认
base
Document
如上所示,我将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
Document
//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
Document
//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
Document
//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
Document
// 定义入口模块
define(function(require,exports,module){
// 引入其他模块
var M = require('module/runtime')
module.exports.state = M;
})
上面的例子模拟了类似测试时的场景,将模块路径进行了转换