一、SeaJs

一、SeaJs

seajs是国内的一套模块化开发框架,由淘宝工程师王伯写的,有中文文档,学习简单

开源代码库

中文文档

Seajs出现的比较晚,因此借鉴了,nodejs的commonjs规范(加载时同步的),但是前端使用文件是要异步加载文件的,加载完成之后才能使用,又借鉴了前端的AMD规范,seajs的规范称之为cmd规范,这套框架在使用的时候,建议我们使用commonjs规范

1.1 体验seajs

引入seaja之后会向全局暴露两个变量: seajs, define

在模块外部引入其它模块要是用use方法

  • 第一个参数是模块文件的地址,是一个数组,数组中的每一项都是一个模块地址(如果引入的只有一个文件,可以省略数组)

  • 第二个参数是回调函数

  • 函数中的参数就是前面模块向外暴露的功能

  • 作用域是window

seajs引入文件的路径是相对于seajs所在的文件目录(seajs所在的目录就是根目录)

通常我们将seajs放在最外面与index.html文件在同一目录)为了引入seajs方便

seajs对js文件敏感, 因此可以省略js后缀名称

U3HFJg.png

1.2 配置模块

所有源码都存放在 GitHub 上:seajs/examples,目录结构为:

1
2
3
4
5
6
7
8
9
10
examples/
|-- sea-modules 存放 seajs、jquery 等文件,这也是模块的部署目录
|-- static 存放各个项目的 js、css 文件
| |-- hello
| |-- lucky
| `-- todo
`-- app 存放 html 等文件
|-- hello.html
|-- lucky.html
`-- todo.html

我们从 hello.html 入手,来瞧瞧使用 Sea.js 如何组织代码。

引入sea.js文件:

1
<script src="examples-master/sea-modules/seajs/seajs/2.2.0/sea.js"></script>

使用seajs.config 配置模块:

1
2
3
4
5
6
7
8
9
10
// 配置模块
seajs.config({
// 1、./是当前目录
// 2、../是父级目录
// 3、/是根目录
base: "./examples-master/sea-modules/",
alias: {
"jquery": "jquery/jquery/1.10.1/jquery.js"
}
});

通过seajs.use 使用模块:

1
2
3
4
5
6
7
if (location.href.indexOf("?dev") > 0) {
// 加载入口模块
seajs.use("../static/hello/src/main");
}else {
// 加载入口模块
seajs.use("examples/hello/1.0.0/main");
}

sea.js 在下载完成后,会自动加载入口模块。

U3zvhq.png

seajs:

1
2
3
seajs.use(["jquery"], function(){
console.log(this, arguments);
});

U8SAE9.png

  • seajs本身是一个对象, 对象中包含各种功能函数以及相关信息

  • seajs.config 是规定如何配置模块的

  • seajs.use 是规定如何使用模块的

define:

U8Se9x.png

  • define: 规定如何定义模块

1.3 定义模块

define函数用来定于模块,可以接受3个参数,因此提供了六种定义模块的方式:

  • 传递一个参数:

    • 当传递的是值类型的时候(数字, 字符串, boolean)

      • 这种传递数据的方式会直接作为接口暴露出来
    • 当传递的是引用类型的时候(arr, obj)

      • 这种方式会作为接口暴露
    • 当传递一个函数的时候(90%以上都是使用这种方式,因为它是基于comminjs规范)

      • 此时有三个参数,分别是:

        • require 用来引入其它模块的

        • exports 向外暴露功能的

        • module 模块信息

      • 作用域是全局作用域,所以不要使用this添加属性或者方法

        • 如果使用this 将会污染全局作用域
      • 暴漏的接口是由exports或者module定义的

  • 传递两个参数:

    • 第一个参数如果是一个字符串

      • 表示模块的id

      • 此时,不能直接在use方法中使用这个模块的(要配合require方法使用)

    • 第一个参数如果是一个数组

      • 表示模块的依赖集合 (数组中的每一项,不管有没有使用,都会被加载)
    • 第二个参数是回调函数 (同第三种定义模块方式中的函数表现一致)

  • 传递三个参数:

    • 第一个参数是一个字符串

      • 表示模块的id
    • 第二个参数是一个数组

      • 表示模块的依赖集合
    • 第三个参数是回调函数(同第三种定义模块方式中的函数表现一致)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 定义模块的第一种方式
// 传递数字
define(1);
// 传递字符串
define("abc");
// 传递布尔值
define(true);

// 第二种方式
// 传递数组
define([1, 2, 3]);
// 传递对象
define({
color: "red",
width: 100
});

// 第三种方式
define(function() {
console.log(this);
console.log(arguments);
});

// 第四种方式
define("abc", function() {
define("modules/main", function() {
console.log(this);
console.log(arguments);
});

// 第五种方式
define(["modules/dom"], function() {
console.log(this);
console.log(arguments);
});

// 第六种方式
define("abc", ["modules/dom"], function() {
define("modules/main", ["modules/dom"], function() {
console.log(this);
console.log(arguments);
});

1.4 require模块

在一个模块中想要引入其它模块要分为两步:

  • 第一步 找到这个模块的对应的文件

  • 第二步 在这个文件中读取这个模块

  • Require是根据模块的id加载这个模块的

1) require 不能简写

1
2
3
4
5
6
// require不能被简写
define(function(req, exports, module)
// 引入color.j
var color = req("js/color");
console.log(color);
});

2) require 不能被修改

  • require不能被赋值

  • require不能赋值给其它变量

  • require不能作为子函数的参数传递

  • require不能在子函数中修改(上面的三点)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// require不能被修改
define(function (require, exports, module) {
// 1 require不能被赋值
// require = 123;
// 2 requier不能赋值其它变量
// var a = require;
// 3 不能在子函数中作为参数传递
function demo(require) {
// 4 require在子函数中不能被赋值
require = 123;
var color = require("js/color");
console.log(color);
}
demo(require);
// 引入color.js
// var color = a("js/color");
// console.log(color);
});

3) require参数只能是一个字符串,不能拼接

1
2
3
4
5
6
// 不能拼接
define(function(require, exports, module) {
// 引入color.js
var color = require("js" + "/" + "color.js");
console.log(color);
});

1.5 加载具有id的模块

  • 加载具有id的模块需要分为两步走:

    • 第一步在依赖集合中加载该模块文件

    • 第二步通过require去加载指定id模块

  • 如果一个模块文件中有两个相同id的模块,前面的会覆盖后面

  • 如果一个模块文件中有两个没有id的模块, 后面的会覆盖前面的

  • 一个模块文件可以存在多个具有id的模块,引入的模块是以指定的id模块为准

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 两个相同id的模块
define("myid", function(require, exports, module) {
exports.a = 11;
});
define("myid", function(require, exports, module) {
exports.a = 10;
});

// 两个没有id的模块
define(function(require, exports, module) {
exports.a = 11;
});
define(function(require, exports, module) {
exports.a = 10;
});
// 两个不同id的模块
define("myId", function(require, exports, module) {
exports.a = 10;
});
define("myId1", function(require, exports, module) {
exports.a = 11;
});

1.6 暴露接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
console.log(arguments)
//第一种向外暴露接口的方式
exports.a = 10;
//这种方式是绝对不允许的
exports = {
b: 1
}
//第二种向外暴露接口的方式
module.exports.a = 11;
//第 3 种向外暴露接口的方式
module.exports = 123;
//第 4 种向外暴露接口的方式
//这种方式会覆盖上面的方式
module.exports = {
a: 1,
b: 2
}
//第 5 种向外暴露接口的方式
//外部使用的时候,要作为方法来使用
module.exports = function() {
console.log(123);
}
//第 6 种向外暴露接口的方式
return 1;
return "abc"
//第 7 种向外暴露接口的方式
return {
a: 1,
b: 2
}
//第 8 种向外暴露接口的方式
return function() {}
//第 9 种向外暴露接口的方式
define(1);
define("1");
//第 10 种向外暴露接口的方式
define({
a: 1
});

1.7 暴露接口优先级

return > module.exports > exports

1.8 模块信息

每一个模块,都有一个对象来存储模块的信息

  • id: 表示模块的id

  • uri: 模块的文件路径

    • 默认情况下(如果一个模块没有显示的id)id与模块文件路径相统一
  • exports: 向外暴露内容的对象

  • dependencies: 模块依赖集合,是一个数组,数值中每一个文件就是依赖集合中的成员。

  • deps: 根据依赖集合产生的

  • status: 模块的状态

U8SujO.png

点击查看

本文标题:一、SeaJs

文章作者:Mango

发布时间:2020年07月14日 - 13:03:58

最后更新:2020年07月14日 - 13:27:10

原始链接:https://mango185.github.io/post/ae7e3172.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------------本文结束 感谢您的阅读-------------------