五、requirejs

五、 requirejs

5.1 体验requirejs

requirejs是第一个模块化开发框架,提出了module transports规范, 基于前段模型的规范(加载时都是异步的),又借鉴于nodejs,也支持comminjs规范,建议我们使用module transports 规范

1
2
3
4
5
requirejs是基于AMD规定
require.js官网
requirejs.org
requirejs.cn
使用requirejsseajs一样要在页面中引入文件才可以使用

根目录:

1
2
3
4
如果没有data-main属性, 默认是以html文件为根目录
如果使用data-main属性, 默认是以data-main属性值为根目录
seajs是以seajs所在的文件目录为根目录
requirejs是以引入html文件的目录为根目录

引入requirejs会向全局暴露3个变量

U8Sb26.png

requirerequirejs是一样的

这里的require方法和seajsseajs对象一样

引入requirejsscript标签上有一个data-main属性,它可以引入项目的入口文件

1
<script type="text/javascript" data-main="js/main.js" src="js/require.js"></script>

除了以上方式还有另外一种方式可以引入项目的入口文件

require方法和seajs.use方法一样的,它也可以引入入口文件

接受两个参数:

  • 第一个参数是模块的依赖集合

    • 必须是数组
  • 第二个参数是回调函数

    • 回调函数中的参数就是前面模块向外暴露的功能 (一一对应的)

    • 作用域是window

requirejsjs文件敏感,因此可以省略.js后缀

1
2
3
4
5
6
7
<script type="text/javascript">
// 引入入口文件
require(["js/main.js"], function(main) {
console.log(this);
console.log(main);
});
</script>

5.2 定义模块

requirejsseajs一样, 都有一个define方法,用来定义模块

  • 可以传递一个参数:

    • 值类型 不能字符串

    • 对象 require也支持

    • 函数

      • 此时函数遵循commonjs规范,requirejs提供了参数注入的技术,想要使用哪个模块就要注入哪个模块

      • 向外暴露功能一定是基于commonjs规范

      • 如果没有注入参数

        • 作用域是window
      • 如果注入参数

        • 作用域是向外暴露功能的对象
  • 可以传递两个参数:

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

    • 第一个参数还可以是数组

    • 第二个参数加载模块的函数

    • 如果第一个参数是字符串,表示模块的id,此时函数遵循commonjs规范(与上面传递函数的表现形式一致)

    • 如果第一个参数是数组, 表示模块的依赖集合, 此时函数遵循的是module transports规范

    • 如果想要使用哪个模块,就必须在依赖集合中注入哪个模块,包括内置模块(require, exports, module),此时函数中的参数是和前面模块向外暴露的接口是一一对应。

    • 如果注入exports和module

      • 作用域指向向外暴露功能的对象
    • 如果没有注入exports和module

      • 作用域是window
  • 可以传递三个参数:

    • 第一个参数是字符串,表示模块的id

    • 第二个参数是数组,表示模块的依赖集合

    • 第三个参数是回调函数,此时的函数遵循module transports 规范

    • 在module transports规范中,定义的任何模块文件,都不要与内置模块的名称相同(require, exports, module)

在工作中,最后一种方式是最常用的(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
// 定义模块
// 值类型
define(1);
// 这种方式是不允许的
define("abc");
define(true);

// 传入对象
define({
color: "red"
})

// 传递函数
define(function(require, exports, module) {
console.log(this);
console.log(arguments);
this.color = "red";
})

// 传递两个参数,第一参数是字符串
define("dom", function(require, exports, module) {
console.log(this);
console.log(arguments);
})

// 传递两个参数,第一个参数是数组
define(["color", "require", "exports", "module"], function(color, require, exportsm, module) {
console.log(this);
console.log(arguments);
this.color = "blue";
})

// 传递三个参数
define("dom", ["color", "require", "exports", "module"], function(color, require, exports, module) {
console.log(this);
console.log(arguments);
})

5.3 引入具有id的模块

当一个模块没有id的时候可以直接引入

当一个模块有id,此时无法直接引入

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

第二步通过require方法指定id(require是异步方法)

comminjs规范不能加载具有id的模块

1
2
3
4
5
6
// 加载具有id的模块
define(["dom", "require"], function(dom, require) {
require(["myId"], function(dom) {
console.log(dom)
});
})

dom.js

1
2
3
define("myId", {
color: "red"
})

5.4 模块的覆盖关系

如果一个模块文件中有两个没有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
23
24
25
26
// 两个没有id的模块
define({
a: 2
})
define({
a: 1
})


// 有两个相同id的模块
define("myId", {
a: 2
})

define("myId", {
a: 1
})

// 两个不同id的模块
define("myId1", {
a: 1
})

define("myId2", {
a: 2
})

5.5 接口定义

在seajs中定义接口的方式:

1
2
3
4
5
exports.接口
module.exports.接口
module.exports = 值类型
module.exports = 对象
module.exports = 函数

以上方式都是基于commonjs规范, requirejs同样适用

1
2
3
return 值类型
return 对象
return 函数

以上三种方式,是基于(module transports)规范的,因为不依赖于 require, exports, module

开发更灵活

define 可以接受值类型,不能接受字符串

除了以上十种方式,当模块函数中注入exportsmodule的时候,作用域是向外暴露功能的对象

因为可以通过this向外暴露接口

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// 定义模块
define(function(require, exports, module) {
// console.log(this);
// console.log(arguments);
// 这种方式绝对不允许
exports = {

}
})

// // commonjs
define(function(require, exports, module) {
// 第1种
exports.a = 1;

// 2
module.exports.a = 1;

// 3
module.exports = 123;

// 4
module.exports = {
a: 1,
b: 2
}

// 5
module.exports = function() {}
})


// module transports
define(function() {
// 6
return 123;

// 7
return {
a: 1,
b: 2
}

// 8
return function() {}
})


// 9
define(1);
define(true);
define("abc"); // 这种方式不允许


// 10
define({
a: 1,
b: 2
})

// this
define(function(require, exports, module) {
console.log(this);
console.log(arguments);
this.color = "red";
})

5.6 模块对象

  • id: 表示的是模块的id, 默认值与uri不一致

  • uri: 模块的文件地址, 是相对于html文件目录

  • 如果没有data-main属性, 路径的前面会多一个./

  • config: 配置模块信息的

  • exports: 暴露功能的接口对象

U8pixf.png

点击查看

本文标题:五、requirejs

文章作者:Mango

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

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

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

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

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