10分钟入门requireJs

引入


下载 requireJs,然后在 head

1
<script src="js/require.js" data-main="js/main" defer async="true"></script>

async 属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持 defer,所以把 defer 也写上。

data-main 属性的作用是,指定网页程序的主模块。在上例中,就是js目录下面的 main.js,这个文件会第一个被 require.js 加载。由于require.js 默认的文件后缀名是js,所以可以把 main.js 简写成 main

基本API


require 会定义三个变量:define, require, requirejs,其中 require === requirejs,一般使用 require 更简短

  • define 从名字就可以看出这个api是用来定义一个模块
  • require 加载依赖模块,并执行加载完后的回调函数

比如我们想写一个 a.js 的模块,实现一个功能:

1
2
3
4
5
6
7
define(function(){
function fun1(){
alert("it works");
}

fun1();
})

这里通过 define 函数定义了一个模块,这是 requirejs 的标准写法。如果想在页面中使用该 js ,可以直接在 html 文件中调用:

1
require(["js/a"]);

如果我们的网页目录如下:

Alt text

并且 index.html 内容如下,通过主动 require 的方式调用 a.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js/lib/require.js"></script>
<!-- 这里只是主动加载了a.js,并没有定义加载结束后的回调函数,其功能即为只执行a.js中代码 -->
<script type="text/javascript">
require(["js/a"]);
</script>
</head>
<body>
<span>body</span>
</body>
</html>

这时候网页就会弹出一个alert 对话框:
Alt text

如果将 index.html 写成如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js/lib/require.js"></script>
<script type="text/javascript">
require(["js/a"], function(){
alert("call back!");
});
</script>
</head>
<body>
<span>body</span>
</body>
</html>

那么会在 ‘It works’ 后,再弹出一个对话框:
Alt text

加载文件和全局配置

也许你会说,这样调用的方式,如果我有 a,b,c,d… 等 js 代码,不还是得一个个写到 head 里的 <script> 标签内调用么。不急,下面才是重点。

首先我们在 js 目录下新建一个 main.js

Alt text

然后在 main.js 中写如下代码:

1
2
3
4
5
6
7
8
9
require.config({
paths : {
"a" : "js/a"
}
})

require(['a'],function(){
alert('finish load');
});

然后在 index.html 中这样写:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js/lib/require.js" ></script>
<script>
require(['js/main']);
</script>
</head>
<body>
<span>body</span>
</body>
</html>

这里用到了 require.configrequire.config 是用来配置模块加载位置的。即给我们的 js 模块,取一个 别名,之后进行 require 的时候,就不用以输入路径的方式来调用,直接写这个 别名 就行。

可以看到上面代码写 require 的时候,直接是使用 require(['a'] 而不是之前的 require(["js/a"]

这样如果我们有很多的代码,就可以在 main.js 中,先配置各个模块的路径,并起别名,然后挨个 require 调用就是了。就不用对 head 标签进行修改。

同时如果我们在 index.html 中这样写:

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

这里 data-main 属性的作用是,指定网页程序的主模块。在上例中,就是js目录下面的 main.js,这个文件会自动被 require.js 加载。这样我们就只用写一个 <script> 标签,就实现了对所有的 js 模块的调用。

data-main 还有一个重要的功能:
script 标签指定 data-main 属性时,require 会默认的将 data-main 指定的 js 为根路径。即之后如果写 require 来调用 js 模块,不需要再添加 ‘js’ 目录前缀。

async 属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持 defer,所以把 defer 也写上。

下面是使用 data-main 属性时候的 html 和 js 文件写法:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js/lib/require.js" data-main="js/main" defer async="true"></script>
</head>
<body>
<span>body</span>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
require.config({
//这里看到指定 a.js 模块路径的时候,并没有写上其路径前缀 'js/',这就是 data-main 属性的作用
paths : {
"a_alias" : "a"
}
})

require(['a_alias'],function(){
alert('finish load');
});

加载不符合AMD规范模块


标准的写法是需要使用一个:

1
2
3
define(function(){
// your code here
});

将你的代码写在这个 define 内部。但是我们如果想要使用一个不是这种标准的 js 模块怎么破?

这里就要使用到 shim。我们看下面的完整配置 main.js

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
requirejs.config({
paths: {
jquery: [
'lib/jquery.min'
],
bootstrap: [
'//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min', // 这里支持输入多个备选路径,前一个失败就是选择下一个
'lib/bootstrap.min'
],
my:'my'
},
shim:{
'bootstrap':{
deps:['jquery'] // 这里指定依赖关系,bootstrap 要在 jquery 加载完成之后再加载
},
'my':{
deps:['jquery','bootstrap'],
exports:'my_alis'
}
}
});

require([
'jquery','bootstrap','my'
],
function($, my_alis){
// my 中的变量和函数,只在这里有效。
});

这里假设我使用了 jquerybootstrap 模块,还有一个自己写的业务脚本 my.jsmy.js 因为要依赖于 jquerybootstrap 所以在依赖关系中写了上面的配置。

关键在于 export 关键字的声明。这样我们就可以加载一个没有使用 AMD 规范编程的 js 模块了。并且模块的所有变量,和函数,都不是在全局域的,只在 回调函数中有效。从而避免了全局变量的污染问题。

参考:


0%