前端模块化(五):RequireJs

1 概述

RequireJS是一个JS模块加载器,遵循AMD规范。它主要是为了实现JS文件的异步加载以及管理模块之间的依赖性。下面,我们通过一下例子来了解requirejs的使用。

2 RequireJs的使用

首先,我们创建一个项目,主要文件目录如下:

 

2.1 加载模块

在使用requieJS模块化开发之前,我们需要下载require.js,可以通过npm下载或者在官网获得。然后,创建两个文件index.html以及index.js,示例代码一如下:

//index.html
<!DOCTYPE html>
<html>
      <head >
                 <title>require栗子</title>
       </head>
         <body>
             <div>
                 <h1>这是require栗子</h1>
                 <button id="clickBtn">点击展开</button>
                 <p id="showMsg"></p>
             </div>
             <script data-main="js/ctr/index" src="js/lib/require.js" type="text/javascript"></script>
         </body>
</html>
//js/ctr/index.js

require.config({
         paths: {
                 'jquery': '../lib/jquery'
         }
}); 

require(['jquery'], function($) { 
         $(document).on('click', '#clickBtn', function() {
                 $('#showMsg').html('看看jquery加载进来了没有');
         }); 
}); 

使用<script>标签来引入requireJS,这个是毫无疑问的。然后在<script>标签中发现有个data-main属性,这是什么意思呢?在index.js文件中出现的require.config以及require有什么作用呢?下面,我们逐一分析一下。

2.1.1  data-main

data-main属性,它的作用是作为一个出入口,指定入口主模块。也就是说,require.js会在加载完成以后通过回调方法去加载这个data-main里面的js文件,所以这个js文件被加载的时候,RequireJS已经加载执行完毕。在示例代码一中,加载完requirejs后,便会根据data-main属性加载js/ctr/index.js文件。

data-main还有一个重要的功能,当script标签指定data-main属性时,require会默认的将data-main指定的js为根路径。在上面的实例代码一中,把js/ctr作为了根目录,相当于默认设置了配置,示例代码二如下:

require.config({

    baseUrl : "js"

})

当然,这个默认设置被index.js里面的require.config配置所覆盖,所以没有生效。

 

2.1.2  require.config

require.config的作用就是配置requireJS的一些参数,然后公共引用。config函数需要传入一个可选参数对象,这个可选参数对象包括了许多的配置参数选项。这些配置参数选项的主要作用如下:

  • baseUrl——用于加载模块的根路径。
  • paths——用于映射不存在根路径下面的模块路径。
  • shims——配置在脚本/模块外面并没有使用RequireJS的函数依赖并且初始化函数。
  • deps——加载依赖关系数组

在示例代码一中,我们定义了jquery文件的路径,设置了模块名为‘jquery’。 这里,require是以当前主模块index.js路径为起点去寻找jquery.js文件的,所以在paths配置项中,我们设置的jquery路径要‘../’回到上级目录才能寻找到jquery。在主模块中,调用的时候可以直接使用模块名‘jquey’,require会根据config配置项中定义的路径去加载js/lib/jquery.js。require.config的配置项优先权高于data-main,可以覆盖data-main的默认配置。

 

2.1.3  require

require函数用于加载模块依赖但并不会创建一个模块。

require()函数接受两个参数。第一个参数是一个数组,表示所依赖的模块,上例就是['jquery'],即主模块依赖这个模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。

在上面的实例代码一中,require函数异步加载了jquery模块,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,由此解决了模块依赖性的问题。

 

2.1.4 加载扩展

在示例代码一中,把require.config()放在index.js里面,这样子不够优雅。我们应该把require.config()抽出来,单独放在一个js文件里面,这样方便移植和复用。下面,我们修改idnex.js,把require.config()抽出来放在js/ctr/config.js中。示例代码三如下:

//  js/ctr/config.js总配置文件
define(function () {

         require.config({
                 paths: {
                          'jquery': '../lib/jquery'
                 }
         });

})
//  js/ctr/index.js
require(['config'],function(){//加载配置文件

         require(['jquery'], function($) {
             $(document).on('click', '#clickBtn', function() {
                 $('#showMsg').html('看看jquery加载进来了没有');
             });
         });

})

 

2.2  define模块定义

require.js加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写。

具体来说,就是模块必须采用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。

创建一个文件a.js,它定义了一个modA模块。示例代码四如下:

//js/ctr/a.js
define(function (){

    var funA = function (x,y){
      return x+y;
    };

    return {
      funA: funA
    };

});
//js/ctr/index.js
require(['jquery', 'a'], function ($ ,modA){

         $(document).on('click', '#clickBtn', function() {
                 $('#showMsg').html('看看jquery加载进来了没有');
         });
    console.log(modA.funA (1,1));//在控制台输出结果2

});

 

2.3  加载非AMD规范的模块

通过require加载的模块一般都需要符合AMD规范即使用define来申明模块,但是部分时候需要加载非AMD规范的js,这时候就需要用到另一个功能:shim。shim是require.config配置对象中的一个属性,专门用来配置不兼容的模块。具体来说,每个非AMD规范模块要定义exports值和deps数组。

(1)exports值(输出的变量名),表明这个模块外部调用时的名称。我们有时候会用到underscore类库,但是他并没有实现AMD规范,那我们可以这样配置,示例代码五如下:

require.config({

    shim: {
        "underscore" : {
            exports : "_";
        }
    }

})

这样配置后,我们就可以在其他模块中引用underscore模块,示例代码六如下:

require(["underscore"], function(_){

    _.each([1,2,3], alert);

}) 

(2)deps数组,表明该模块的依赖性。例如,我们经常会用到jquery插件,而且这些插件基本都不符合AMD规范,比如jquery.form插件,这时候就需要将form插件"垫"到jquery中,示例代码七如下:

require.config({

    shim: {        
        "jquery.form" : {
            deps : ["jquery"],
         exports: 'jqueryForm'
        }
    }

})

 

3 总结

本文对RequireJS的使用做了简单的介绍,大家如有需要对RequireJS进行更深入的了解,可以直接看源码或者查看官方API文档。下一篇我们开始介绍CMD规范,进一步了解模块化的演进。

 

posted @ 2017-12-03 21:35  灰锅  阅读(662)  评论(0编辑  收藏  举报