require.js使用教程

require.js API:http://requirejs.org/docs/api.html#config

参考文档:http://www.tuicool.com/articles/bu6Zbi

require.js优点

1.实现JS文件的异步加载,避免网页被堵塞

2.管理模块之间的依赖性,便于代码的编写和维护

 

基本语法及使用

1.引用require.js

在页面头部head标签内引用require.js,如下:

<script src="js/require.js"></script>

 但是这个加载这个文件也可能造成网页失去响应,也是同步加载,我们可以加上defer和async属性,如下:

<script src="js/require.js" defer async="true"></script>

 Asynce属性表明文件需要异步加载,IE不支持这个属性,值支持defer,所以上面把这两个属性都加上。接下来,看看require.js启动加载脚本的初始化方式,requireJS支持属性data-main这个属性来加载初始化的js文件,如下:

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

上面的意思是:先异步加载require.js文件,完成后继续异步加载app.js文件,上面app.js后的.js可以去掉,require.js默认后缀名是.js

 

2.定义模块文件

require.js编写模块不同于其他脚本文件,它良好的使用define来定义一个作用域避免污染全局空间,它可以显示出其依赖关系,并以函数(模块定义中的那个函数)参数的形式将这些依赖注入

 

做一个demo,新建如下一个项目文件:

 

 现在app/b.js中添加模块定义代码:

define(function(){
 var add = function(x,y){
    return x + y;
 };
 return{
    add:add
 }
});

 使用define定义模块,下面我们需要在app.js里面加载b.js模块,代码如下:

require(['app/b'],function(b){
   console.log(b.add(1,1));
});

 

在head标签内动态生成文件,如下:

<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="js/require.js" defer="" async="true" data-main="js/app"></script>
<script>	
</script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="app" src="js/app.js"></script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="app/b" src="js/app/b.js"></script>
</head>

 可以看到加载顺序是require.js-->app.js-->b.js

上面是使用define定义一个函数,我们可以直接定义一个对象(可以解决污染全局变量的问题,关于define更多内容请看《AMD》一文),现在在a.js中定义一个对象:

define({
  name:'jiaqing',
  age:22
});

 app.js初始化代码改为:

require(['app/a'],function(a){
 console.log(a);
)};

 结果可以自己测试下

 

3.AMD模块定义规范

①:

define(function(){
 return x:x
});

②有依赖项:

define(['data'],function(data){

});

③定义对象:

define({
data:'';
ui:'';
});

④具名模块:

define('index',['data'],function(data){
//todo
});

⑤包装模块:

define(function(require,exports,module){
  var base = require('base');
//这一句相当于define的模块依赖id为‘base’的模块
  exports.show = function(){
  //todo with module base
  }
  //exports.show这句相当于 return {show:}
});

 这个书写格式和node.js比较像,可以使用require获取模块依赖,使用exports或者module.exports导出API

更多AMD的细节参见《AMD》一文,require.js很好的实现了AMD规范,所以也有上面的定义模块方式

 

举个例子理解第五种写法,想引用a.js,修改app.js代码如下:

define(function(require,exports,module){
  var a = require('app/a');
  console.log(a);
  exports.show = function(){
  
  }
});

 注意:1.书写require.js遵循一个文件一个模块

 2.不要手动写模块名标识

 

4.require.js配置项

1.baseUrl:指定本地模块的基准目录,即本地模块的路径是相对于哪个目录的,该属性通常由require.js加载时的data-main属性指定。

项目结构还是上面的,在index.html页面<head>中引用 <script src="js/require.js" defer async="true" data-main="js/app"></script>

在app.js中写如下代码:

require.config({
  baseUrl:'js/app'
});

require(['a','b','c'],function(a,b,c){
});

 

看项目文件图,index.html和js目录是同一个目录下的,都是放在require文件夹里面的,所以定义baseUrl:‘js/app’会自动解析成require/js/app/ 所以require(['a','b','c'])的话,会自动到require/js/app/目录下去查找a.js,b.js,c.js,找到了就可以加载出来

如果未显式设置baseUrl,则默认值是加载require.js的html所处的位置,如果使用了data-main属性的话,则该路径成了baseUrl。

如果把上面app.js中的require.config去掉则对‘a’,‘b’,‘c’的引用在浏览器中被解析成:

<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="js/require.js" defer="" async="true" data-main="js/app"></script>
<script>
	
</script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="app" src="js/app.js"></script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="a" src="js/a.js"></script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="b" src="js/b.js"></script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="c" src="js/c.js"></script>
</head>

 也就是在app.js所在的js目录下查找他们

 

2.paths:为那些模块名称没有直接存在baseUrl内的模块做路径映射,设置paths的起始位置是相对于baseUrl的,除非该path设置是以“/”开头或含有URL协议(http://或https://)

模块名称对应的路径名不应该包含扩展名,因为路径名也可以用于映射目录,如果映射的是模块,将会自动加上.js扩展名

例子:

将上面app.js代码改为:

require.config({
  baseUrl:'js/lib',
  paths:{
     app:'../app'
  }
});

require(['app/a'],function(a){
});

 则页面加载显示如下:

<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="js/require.js" defer="" async="true" data-main="js/app"></script>
<script>
	
</script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="app" src="js/app.js"></script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="app/a" src="js/lib/../app/a.js"></script>
</head>

 可以看到paths是相对于baseUrl配置项生成的,'..'解析到上层的js目录。require(['app/a'])实际上就是解析到js/app/a.js了。

 

3.shim:为旧的,传统的且没有使用define()声明依赖和模块值的“浏览器全局”脚本配置依赖,输出值和用户初始化

 

4.其他配置属性看文档

 

5.内部机制

require.js加载每个模块作为scriptTag,使用head.appendChild()方法,在模块定义时,require.js等到所有的依赖都加载完毕,会为函数的调用计算出正确的顺序,然后在函数中通过正确的顺序进行调用

猜你喜欢

转载自xiaoxiaoher.iteye.com/blog/2379431