必威体育Betway必威体育官网
当前位置:首页 > IT技术

RequireJs

时间:2019-06-25 22:44:16来源:IT技术作者:seo实验室小编阅读:89次「手机版」
 

require

RequireJs

RequireJS是一个js脚本加载器,它遵循AMD(Asynchronous Module Definition,即异步模块加载机制 )规范。实现js脚本的异步加载,不阻塞页面的渲染和其后脚本的执行,并提供了在加载完成之后执行相应回掉函数的功能。

为什么使用RequireJs

实例1:

// index.html
<!DOCTYPE html><html>
<head>
     <script type="text/javascript" src="a.js"></script>
 </head>
 <body>
   <span>body</span>
 </body></html>

 // a.js
 function fun1(){ alert("it works");} fun1();

当运行上面两种例子时,alert执行的时候,html内容是一片空白的,即body并未被显示,当点击确定后,才出现,这就是js阻塞浏览器渲染导致的结果

使用require改写上面例子:如下:

// index.html
<!DOCTYPE html>
<html>
<head>
      <script type="text/javascript" src="require.js"></script>
      <script type="text/javascript">
            require(["a"]);
      </script>
</head>
<body> <span>body</span> </body>
</html>

// a.js
define(function(){
     function fun1(){
          alert("it works");
      }
     fun1();
})

浏览器提示了”it works”,说明运行正确,但是有一点不一样,这次浏览器并不是一片空白,body已经出现在页面中

实例2:

在我们引入js文件时,由于js文件之间存在依赖关系,因为必须严格保证加载的顺序,依赖性最大的模块一定要放在js引入的最后面,这样当依赖关系比较复杂的时候,代码的编写和维护相对就会困难,例如:

// index.html
<!DOCTYPE html>
<html>
  <head>
        <meta charset="utf-8" />
        <title></title>
  </head>
  <body>
  </body>
  <script src="js/jquery.min.js"></script>
  <script type="text/javascript" src="js/index.js"></script>
</html>

// index.js
(function(){
      $("body").css("background-color","lightblue");
})();

在上述demo中,index.js的引入必须要在jquery引入之后。这样在使用框架和js文件较多的时候,他们的导入顺序就会变的复杂。

由上可知:requirejs可解决如下问题:

  • 防止js加载阻塞页面渲染。
  • 管理模块之间的依赖,便于代码的编写和维护。
  • 使用程序调用的方式加载js,防出现如下丑陋的场景
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b.js"></script>
<script type="text/javascript" src="c.js"></script>
<script type="text/javascript" src="d.js"></script>
<script type="text/javascript" src="e.js"></script>
<script type="text/javascript" src="f.js"></script>
<script type="text/javascript" src="g.js"></script>
<script type="text/javascript" src="h.js"></script>
<script type="text/javascript" src="i.js"></script>
<script type="text/javascript" src="j.js"></script>

基本API

  • define:用于定义一个模块
  • require:加载依赖的模块,并执行加载完成后的回掉函数

简单键值对

define({
    name: "john",
    age : 20,
    sex : "femal"
});

这种情况用途不是很大,一般用于数据模拟 ,在引入后,回掉函数注入的参数就是该键值对的object对象,如下:

require(['js/index'],function(data){
        console.log(data);
});

无依赖的函数式模块定义

define(function(){
      function fn(){
            alert('it works');
      }
      fn();
});

有依赖的函数是模块定义:当模块a依赖与模块b的时候,那么在定义模块a时,需要对模块b进行加载,如下:

// index.html
<script src="js/require.js"></script>
<script>
      require(['js/index'],function(){
            console.log('模块加载成功');
      });
</script>

// index.js
define(['./jquery.min'],function(){
      $('body').css('background','lightgreen');
});

模块的加载(require中的依赖是一个数组,即使只有一个模块,也需要写成数组的形式;第二个参数为callback,用于处理加载完毕后的逻辑,如下:)

require(["js/index"],function(){
     alert("load finished");
})

文件的加载

1) 在上面的demo中,如果index.js依赖模块jquery,那么是通过如下方式引入的,这个./的路径是相对index.js的相对路径require(['./jquery.min'],function(data){});

  • 除上面的方式以外,我们还可以通过require.config()方法,对模块的加载行为进行定义
  • require.config是用来配置模块加载位置,简单点说就是给模块起一个更短更好记的名字,比如将百度的jquery库地址标记为jquery,这样在require时只需要写[“jquery”]就可以加载该js,本地的js我们也可以相应配置:
require.config({
    paths : {
        "jquery" : "js/jquery.min",
        "index" : "js/index"
    }})

require(["jquery","index"],function($){
    $(function(){
        alert("load finished");
})})

2)除令模块有一个更好记的模块名称,paths还有一个重要的功能,就是可以配置多个路径,如果远程的cdn库没有加载成功,可以加载本地文件,如下当引入jquery时,如果百度的jquery没有加载成功,那么会加载本地的:

require.config({
    paths : {
        "jquery" : ["http://libs.baidu.com/jquery/2.0.3/jquery", "js/jquery"]
     }
})

3)在上面的配置中,我们发现每个文件都是在js文件夹下,此时我们可以使用设置baseUrl,这样在下面的路径中就不选哟每次都写’js/’,如下所示:

require.config({
      baseUrl:'js',
      paths: {
            "jquery": "jquery.min",
            "bootstrap": "bootstrap"
      }
})

4)上面例子中的callback函数中发现有$参数,这个就是依赖的jquery模块的输出变量,如果你依赖多个模块,可以依次写入多个参数来使用:

require(["jquery","underscore"],function($, _){
     $(function(){ _.each([1,2,3],alert); }
)})

如果某个模块不输出变量值,则没有,所以尽量将输出的模块写在前面,防止位置错乱引发误解

全局配置

  • 上面的例子中重复出现了require.config配置,如果每个页面中都加入配置,必然显得十分不雅,requirejs提供了一种叫”主数据”的功能, 我们可以将所有的require.config配置放到main.js中,在页面中调用它
require.config({
      paths: {
            "jquery": "js/jquery.min",
            "bootstrap": js/"bootstrap"
      }
})
  • 然后再页面中使用下面的方式来使用requirejs:

    <script data-main="js/main" src="js/require.js"></script>

  • 注意:由于在main.js中所设置的脚本是异步加载的,所以如果在页面中配置了其它的js加载,则不能保证他们所依赖的ja已经加载成功,如下,在加载的时候,可能会导致index.js中需要的依赖还未加载完成:
<script data-main="./main.js" src="js/require.js"></script>
<script src="js/index.js"></script>

因此:需要使用require(['js/index'])对js进行引入,或者对main.js使用script标签进行引入

第三方模块

  • 通过require加载的模块一般都需要符合AMD规范即使用define来申明模块,但是部分时候需要加载非AMD规范的js,这时候就需要用到另一个功能:shim:

1)非AMD模块输出,将非标准的AMD模块变成可用的模块,例如:在老版本的jquery中,是没有继承AMD规范的,所以不能直接require[“jquery”],这时候就需要shim

require.config({
  shim: {
    "jquery" : {exports : "$"}
  }
})

2)插件形式的非AMD模块,我们经常会用到jquery插件,而且这些插件基本都不符合AMD规范,比如jquery.form插件,这时候就需要将form插件加入到jquery中:

require.config({
  shim: {
    "jquery.form" : {
      deps : ["jquery"]    // jquery.form所依赖的模块
    }
  }
}) 
require.config(["jquery", "jquery.form"], function($){
  $(function(){
    $("#form").ajaxSubmit({...});
  })
})

3)在shim中还有一个属性为exports,exports为导出的对象,用法如下:

// operation.js
var  myOperation = {};   // 很重要,和shim中exports值必须一致
myOperation.add = function(num1, num2) {
    return num1 + num2;
};
myOperation.max = function() {
    return Math.max.apply(Math, [].slice.call(arguments));
}

// main.js
require.config({
      baseUrl:'js',
      paths: {
            "myOperation":"operation"
      },
      shim: {
      "myOperation" : {
            exports:"myOperation"
      }
      }
})

// index.js
require(['myOperation'],function(myOperation){
      console.log(myOeration);
});

注意:require.config配置shim中exports的值,一定要与相关文件中暴露出全局变量名称一致

相关阅读

分享到:

栏目导航

推荐阅读

热门阅读