使用require.js

requirejs使用入门javascript

什么是requirejs?

  RequireJS的目标是鼓励代码的模块化,它使用了不一样于传统<script>标签的脚本加载步骤。能够用它来加速、优化代码,但其主要目的仍是为了代码的模块化。它鼓励在使用脚本时以module ID替代URL地址。html

RequireJS以一个相对于baseUrl的地址来加载全部的代码。 页面顶层<script>标签含有一个特殊的属性data-main,require.js使用它来启动脚本加载过程,而baseUrl通常设置到与该属性相一致的目录。java

 

为何要使用require.js?

  咱们在作项目的过程当中,每每都须要加载不少个js文件,以下所示:jquery

  <script src="1.js"></script>
  <script src="2.js"></script>
  <script src="3.js"></script>
  <script src="4.js"></script>
  <script src="5.js"></script>
  <script src="6.js"></script>

 

  这样的写法的缺点是Js会阻塞渲染页面,而且文件越多, 那么等待的时间也就越长,而且文件多的状况下每每还存在文件间依赖的问题, 有时候比较复杂,那么文件间的依赖就成了问题。git

  因此require.js主要就是为了解决下面的两个问题:github

(1)实现js文件的异步加载,避免页面失去响应。ajax

(2)管理项目之间的依赖性,便于代码的维护和管理。api

 

如何使用require.js?

  require.js下载地址数组

  使用require.js很是简单,只须要在页面中使用一个require.js便可,以下所示:浏览器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>require</title>
  <script src="./require.js" data-main="js/main" type="text/javascript"></script>
</head>
<body>
  <!-- your code is here -->
</body>
</html>

 

  即咱们在html文件中只须要使用一个require.js文件的引入便可,而后data-main引入的是网页程序的主模块,这个文件会被require.js第一个加载,因为require.js默认文件的后缀名为.js,因此这里咱们写成main便可。

  

如何写主模块main.js

  什么是主模块?

    主模块就是入口文件,它是require.js加载执行的第一个文件,这就是主模块,而且其余的全部js文件将在这里被引入执行。

  为何要使用主模块?

    咱们知道require.js在index.html惟一的被引入,而没有引入其余js文件,这也是为了方便管理。 那么内部机制就要求须要这么一个主模块,而后就能够很好的管理模块之间的关系,试想若是没有这么一个主模块,那么require.js也会无从下手的。

  main.js中怎么写呢? 若是咱们只须要这一个js就够了,好比就执行alert("hello");那么main.js文件中只有这么一句:

alert("hello");

  而后打开html文件时,就会alert("hello");了,可是咱们使用require.js不可能就使用这么一个文件,不然就不用require了。 

  真正的状况是: 主文件main.js依赖于其余文件, 这时就要使用AMD规范来定义require()函数。以下所示:

 // main.js
  require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
    // some code here
  });

  即接受的第一个参数是一个数组,指定模块名称(不带.js的文件), 而后第二个参数是一个函数,其中的参数暴露出了模块中暴露的方法,而后咱们就能够在回调函数中使用这些模块了。

  require()异步加载moduleA,moduleB和moduleC,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。

  

  例子

  好比以前的index.html中的body部分是<div class="wrap"></div>,而后引入了require.js并指定了main.js为入口文件,在main.js中定义以下:

require(['jquery'],function ($) {
  $('.wrap').html("hello, world!");
});

  即咱们只引入了jquery,而且在回调函数中将$暴露出来并使用,那么启动index.html文件以后,咱们就能够在页面上看到渲染的hello, world了。 注意: 此时的目录结构以下:

     

  因此:咱们须要注意下面的几点:

  • require.js会默认认为require()中第一个参数数组里的文件和main.js在同一个目录下
  • 咱们引入的文件即jquery.js,由于默认是.js后缀,因此咱们直接写文件名便可。
  • 在require的回调函数中,咱们使用回调函数中的接口,即若是这里没有定义为$,而是定义为foo,那么咱们就须要使用foo。 

  、

存在的问题若是说依赖文件(如jquery)何main.js文件再也不同一个目录中该怎么引用呢

  好比如今的目录时这样的:

      

 

  那么如今咱们就会发现,你在require函数的第一个参数中写成'jquery'或者‘lib/jquery’或者‘../lib/jquery’或者‘./lib/jquery’都是没法成功的

  这时咱们就须要使用require.config()方法对路径进行配置了。以下所示:

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

 

  若是有多个文件,而且多个文件在一样的目录下,咱们能够定义一个baseUrl, 以下:

  require.config({
    baseUrl: "js/lib",
    paths: {
      "jquery": "jquery.min",
      "underscore": "underscore.min",
      "backbone": "backbone.min"
    }
  });

  若是某个模块在另外一个主机上,咱们能够直接定义其网址:

 require.config({
    paths: {
      "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
    }
  });

 

 

 

如何定义模块?

  在使用require时,咱们用的是AMD的规范进行加载的,因此在定义模块时,也是须要使用AMD规范来定义模块。

  好比如今咱们在和main.js同一个目录下定义一个alert模块:

define(function () {
    var alertName = function (str) {
      alert("I am " + str);
    }
    var alertAge = function (num) {
      alert("I am " + num + " years old");
    }
    return {
      alertName: alertName,
      alertAge: alertAge
    };
  });

  即便用define定义,其中接受一个回调函数做为参数,在这个回调函数中定义模块,最后返回一个对象,对象的属性就是咱们能够调用的方法。

  而后咱们看看如何在main.js中使用:

require(['alert'], function (alert) {
  alert.alertName('JohnZhu');
  alert.alertAge(21);
});

  即便用也很是简单,就是引入alert模块,而后调用其中的alertName和alertName方法便可。  

 

  问题:若是一个模块在定义时须要依赖其余模块怎么办?

  好比这个alert模块须要依赖jquery,那么咱们就能够这么定义:

  define(['jquery'],function () {
      var alertName = function (str) {
        alert("I am " + str);
        $('.wrap').html("I am " + str);
      }
      var alertAge = function (num) {
        alert("I am " + num + " years old");
      }
      return {
        alertName: alertName,
        alertAge: alertAge
      };
    });

  即咱们直接将define的第一个参数(一个数组)中使用jquery, 而后直接使用便可。

  • 注意: 这里显然使用jquery的使用默认路径仍是和main.js在同一个目录下。
  • 这里咱们没有在回调函数中传入参数,可是是能够传的,只是省略了,若是我传入foo,那么就能够用foo(".wrap").html("I am " + str);来使用。
  • 因而main.js在加载alert模块时,会等到jquery模块加载完再执行其中的回调函数。 

 

 

加载非规范的模块

  理论上,require.js加载的模块,必须是按照AMD规范、用define()函数定义的模块。可是实际上,虽然已经有一部分流行的函数库(好比jQuery)符合AMD规范,更多的库并不符合。那么,require.js是否可以加载非规范的模块呢?

   答案是能够的,可是须要在使用require以前,用require.config()方法定义一些他们的特征。

  require.config({
    shim: {

      'underscore':{
        exports: '_'
      },
      'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      }
    }
  });

 

  以前咱们介绍过require.config中的paths,这里又介绍了shim对象,它专门用来配置不兼容的模块。具体来讲,每一个模块要定义:

  (1)exports值(输出的变量名),代表这个模块外部调用时的名称;

  (2)deps数组,代表该模块的依赖性。

   好比,咱们能够这样定义一个jquery插件:

  shim: {
    'jquery.scroll': {
      deps: ['jquery'],
      exports: 'jQuery.fn.scroll'
    }
  }

  即deps说明他是须要依赖jquery的, exports说明能够经过juqery的scroll访问到它。

  

 

require.js插件

  requirejs还提供了一系列的插件供咱们使用。

  domready插件,可让回调函数在页面DOM结构加载完成后再运行。

 require(['domready!'], function (doc){
    // called once the DOM is ready
  });

  text和image插件,则是容许require.js加载文本和图片文件。

  define([
    'text!review.txt',
    'image!cat.jpg'
    ],

    function(review,cat){
      console.log(review);
      document.body.appendChild(cat);
    }
  );

  

 

补充例子

  最近看到有人相似于这样使用require。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>require</title>
  <script src="./require.js" type="text/javascript"></script>
</head>
<body>
  <!-- your code is here -->
  <div class="wrap">
    
  </div>
  <script>
    require(['js/dosomething']);
  </script>
  <script src="js/jquery.js"></script>
</body>
</html>

  dosomething是这样的:

alert('god');
  • 即咱们使用require来引入模块,可是dosomething这个模块并无按照AMD规范来编写。 
  • 咱们能够看到利用require的好处在于能够异步加载文件。 这种用法的好处就是在于require的文件会异步加载。
  • 而且在咱们引入的目的仅仅是执行一些功能,而不须要暴露出方法来,因此能够直接写

 

  

 

 

 

 

 

 

 

参考文档:

http://www.requirejs.cn/

http://www.ruanyifeng.com/blog/2012/11/require_js.html

相关文章
相关标签/搜索