SeaJS
一、seajs
国内模块化开发的框架,由支付宝工程师玉伯所写,有中文文档,学习简单。
seajs出现在requirejs和commonjs之后,所以借鉴了两者,形成CMD规范。运行在浏览器端,异步加载,按需加载。seajs没有实现其他的扩展,只是解决了模块的加载。
seajs学习:
- 模块定义
- 模块加载
- 插件
1.1 体验seajs
当引入seajs文件之后,向全局暴露两个变量
define: 定义模块的函数
seajs:seajs暴露一个对象
在模块外引入其他模块要使用seajs.use方法,该方法一共接收两个参数
第一个参数:是一个数组,数组里面的每一项都是一个模块文件的地址,当引入的模块文件只有一项的时候,可以省略我们的数组直接写路径,seajs对js文件比较敏感,文件后缀.js可以省略
第二个参数:是一个回调函数,函数中的参数就是前面引入模块向外暴露的功能,参数和模块是一一对应的
define:
seajs:
demo:
<script>
// 引入seajs,会想全局暴露两个变量
// define: 定义模块的函数
// seajs:一个对象
// console.log(define);
// console.log(seajs);
// 在非模块文件引入其他模块使用seajs.use
// 引入文件的时候书写路径,参照的不是html文件,参照的是sea.js文件
seajs.use(['module/A', 'module/B'], function(a, b) {
// a就是模块A.js暴露的内容
// b就是模块B.js暴露的内容
console.log(arguments);
});
</script>
res:
1.2 模块的定义
define定义模块
一个参数:
/*
定义模块 define: 三个参数
一个参数:三种
第一种:基础数据类型
第二种:引用数据类型(数组和对象)
第三种: 函数****** 引用最多的
一个模块只能向外暴露一个,后面的会覆盖前面的
*/
// 第一种情况
define(1);
define(true);
define('我爱你塞北的雪!');
// 第二种情况
define([1, 2, 3, 4]);
define({name: 123});
// 第三种情况---------99以上都是用这种方式
define(function(require, exports, module) {
/*
三个参数:
require: 函数,用于在模块内引入其他模块
exports: 模块向外暴露的接口
module: 模块对象,包含整个模块对象的信息,module有一个exports属性,就是向外暴露的接口
exports和module的关系:
exports = module.exports = {}
真正暴露的就是module.exports向外暴露的对象
*/
// console.log(arguments);
// 向暴露的对象添加内容
exports.a = 1;
module.exports.b = 2;
exports.c = 333;
/* 由于 exports = module.exports = {}存在,所以存在两个问题 */
module.exports = {
a: 'a',
b: 'b'
}
exports = {
name: 'sy101',
age: 1
}
console.log(arguments);
/*
注意:
1、module.exports如果指向了新的对象,不能再通过exports来添加属性和方法
2、module.exports如果指向了新的对象,前面添加的值都不存在了
3、不能让exports等于引用类型,赋值方式必须遵守对象的添加方式 exports.key = value
*/
// 返回值对暴露内容的影响?返回值会成为借口暴露的内容
// return 1;
// return 'i miss you';
return {
a: 'aa',
b: 'bb'
}
})
两个参数:
/*
两个参数:两种---根据第一个参数的类型来进行判断的,第二个参数都为函数
第一种: 第一个参数为字符串,表示模块的id
第二种: 第一个参数为数组,表示依赖集合
注意:在模块内部,存在依赖关系的时候,即使只有一个模块也必须写成数组,否则会认为其是一个模块的id
*/
// 第四种: 设置带id的模块,默认情况下,一个文件只能存在一个模块,一个文件想拥有多个模块,给每个模块设置唯一的ID
// define('module/B', function(require, exports, module) {
// console.log('this is module B');
// console.log(arguments);
// })
// 第五种: 第一个参数为数组,代表依赖
define(['module/C'], function() {
// console.log(33333333);
})
三个参数:
/*
三个参数: 模块的id, 依赖集合, 定义模块函数
*/
define('module/D', ['module/E'], function(require, exports, module) {
console.log('this is D');
console.log(arguments);
})
1.3 模块的引入
模块的id冲突的问题:
- 一个模块没有设置id则默认为文件的路径
- 当都没有设置模块id的时候,一个文件存在多个模块,后面的会覆盖前面
- 当一个文件,存在多个相同id的模块,取第一个,前面覆盖后面
- 不同的模块id不冲突的
模块外部引入模块
- 不带id,通过依赖集合和形参的注入引入对应的模块
- 带id的
- 依赖集合加载文件
- 通过seajs.require(模块的id)引入指定的模块
模块内部:
- 不带id的模块: 通过require(模块文件的路径既可以引入) 可以省略依赖集合
- 带id:
- 通过依赖集合加载文件
- 通过require(id)读取指定模块的暴露的内容
模块外部引入模块:
seajs.use(['module/A', 'module/B'], function(a, b) {
console.log(a);
// 在模块外部引入带id的模块
// 1、通过依赖集合进行文件的加载
// 2、通过seajs.require(id)引入指定模块
var data = seajs.require('B1');
console.log(data);
})
模块内部引入其他模块:
define(['module/C', 'module/D'], function(require, exports, module) {
// 引入不带id的
var c_data = require('module/C');
console.log(c_data);
// 引入带id的
var d_data = require('xxoo');
console.log(d_data);
})
1.4 模块对象
dependencies: 模块的依赖集合
deps: 模块依赖集合产生的对象
id: 模块的id
exports: 暴露的接口对象
status: 状态码
uri: 资源地址
URI和URL的区别:
URI: 统一资源标识符
URL:统一资源定位符
URI的范围比URL的范围还要打,URI主要用来描述资源的位置,URL用来描述互联网的资源位置
注意:主入口文件不要设置ID
1.5 seajs模块内部的异步加载
demo:
define(function(require, exports, module) {
// 默认加载的时候,为同步
// require('./A');
// console.log(data);
// console.log(1111);
// 异步加载
require.async('./A', function(A) {
console.log(A);
})
console.log(111);
})
res:
1.6 seajs的配置
seajs.config(配置对象)
1.6.1 配置别名 alias
值是一个对象, 键为新的路径,值为原来的路径
// 当路径比较深的时候,写这个名字费劲,简化
seajs.config({
// 键表示配置项,值表示对应的配置
// 别名配置
alias: {
// 键为新路径,值为原来的路径
D: 'module/A/B/C/D'
},
})
seajs.use(['D'], function(d) {
console.log(d);
})
1.6.2 配置基准路径
键值为:base
默认情况下,以seajs的路径作为参考的,base可以改变基准路径
seajs.config({
// 配置基准路径
base: './module/model/',
})
seajs.use(['main', 'A']);
1.6.3 简化路径
键值为:paths
值为一个对象
键为: 简化后的路径
值为: 原来的路径
seajs.config({
// 简化路径, 简化的是文件夹
paths: {
// 键为设置的路径 , 值为原路径
module: 'xxoo/libs/module'
}
})
seajs.use(['module/A', 'module/B']);
三者的区别:
- alias: 配置文件的别名
- base : 配置基准路径
- paths: 简化文件夹路径