zoukankan      html  css  js  c++  java
  • 使用require.js

    requirejs使用入门

    什么是requirejs?

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

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

    为什么要使用require.js?

      我们在做项目的过程中,往往都需要加载很多个js文件,如下所示:

      <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会阻塞渲染页面,并且文件越多, 那么等待的时间也就越长,并且文件多的情况下往往还存在文件间依赖的问题, 有时候比较复杂,那么文件间的依赖就成了问题。

      所以require.js主要就是为了解决下面的两个问题:

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

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

    如何使用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

  • 相关阅读:
    jQuery事件对象event的属性和方法
    使用CSS3动画库animate.css
    Git常用命令整理
    模拟现实物理效果
    数组排序之选择排序
    数组排序之冒泡排序
    小方块靠着浏览器运动
    轮播图片, 不用滚动视图, 也不用时间计时器
    UIActionSheet
    自动计算高度的方法 iOS, height为0, 可以自动计算weith,
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/6833560.html
Copyright © 2011-2022 走看看