1、为什么使用require.js

作为命名空间; 作为命名空间使用;
异步加载js,避免阻塞,提高性能;
js通过require加载,不必写很多script

2、require.js的加载

require.js下载
下载后,放在指定目录就可以加载了

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

有人可能会想到,加载这个文件,也可能造成网页失去响应。解决办法有两个,一个是把它放在网页底部加载,另一个是写成下面这样:

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

async属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持defer,所以把defer也写上。

这种写法虽然简单,但其实并不推荐,一般的写法还要再加个属性:

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

就像一个c程序总有一个 main 方法作为入口一样,上面这种写法,做了几件事情:
1、加载了 require-jquery.js 文件。注意,官方提供了 require.js和 jquery 的打包版本,推荐。
2、在加载之后,加载入口文件 js/main.js ,注意,main.js 写进去的时候,不需要后缀名。
你的所有其他 js 模块文件,都可以写在 main.js 里面,通过 main.js 加载。

3、require.js的配置

在data-main指定的主文件中,通过require.config来配置,并加载其他js模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require.config({
    baseUrl: 'js/'
    paths: {
        "backbone": "backbone",
        "underscore": "underscore"
    },
    shim: {
        "backbone": {
            deps: [ "underscore" ],
            exports: "Backbone"
        },
        "underscore": {
            exports: "_"
        }
    }
});

baseUrl:指定基路径
paths:模块加载路径
shim:加载非AMD规范模块

    1. exports值(输出的变量名),表明这个模块外部调用时的名称;
    2. deps数组,表明该模块的依赖性。
    3. 主模块可以将项目基础模块加载加来并定义全局方法等
    4. 1
      2
      3
      require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){
           // some code here
         });

      4、定义模块(符合AMD规范)

      require.js加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写。
      具体来说,就是模块必须采用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。
      假定现在有一个math.js文件,它定义了一个math模块。那么,math.js就要这样写:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      // math.js
         define(function (){
           var add = function (x,y){
             return x+y;
           };
           return {
             add: add
           };
         });

      加载方法如下:

      1
      2
      3
      4
      // main.js
         require(['math'], function (math){
           alert(math.add(1,1));
         });

      如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性。

      1
      2
      3
      4
      5
      6
      7
      8
      define(['myLib'], function(myLib){
           function foo(){
             myLib.doSomething();
           }
           return {
             foo : foo
           };
         });

      定义的模块返回函数个数问题

      1、define 的return只有一个函数,require的回调函数可以直接用别名代替该函数名。

      2、define 的return当有多个函数,require的回调函数必须用别名调用所有的函数。

      1
      2
      3
      4
      5
      6
      require(['selector','book'], function(query,book) {
          var els = query('.wrapper');
       
          book.fun1();
          book.fun2();
      });

      此处query 函数是1的情况,book 函数是2的情况。

      5、加载js文件

      到此为止,我们遇到了两个关键词,一个是
      define ,可以用来定义模块(命名空间),第一部分我们讲了;还有一个是 require,可以直接加载其他 js。它除了简单的用法:

      1
      2
      3
      <script>
      require( ["some" ] );
      </script>

      之外,还有和 define 类似的复杂用法:

      1
      2
      3
      4
      5
      6
      <script>
      require(["aModule", "bModule"], function() {
          myFunctionA(); // 使用 aModule.js 中的函数 myFunctionA
          myFunctionB(); // 使用 bModule.js 中的函数 myFunctionB
      });
      </script>

      总结一下,define 是你定义自己的模块的时候使用,可以顺便加载其他js;require 直截了当,供你加载用的,它就是一个加载方法,加载的时候,可以定义别名。

      6、requ.js插件

      require.js还提供一系列插件,实现一些特定的功能。

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

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

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

      1
      2
      3
      4
      5
      6
      7
      8
      9
      define([
           'text!review.txt',
           'image!cat.jpg'
           ],
           function(review,cat){
             console.log(review);
             document.body.appendChild(cat);
           }
         );

      类似的插件还有json和mdown,用于加载json文件和markdown文件。

      7、其他问题

      1、路径与后缀名
      在 require 一个 js 文件的时候,一般不需要加上后缀名。如果加上后缀名,会按照绝对路径加载。没有后缀名,是按照下面的路径加载:

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

      也就是默认加载 data-main 指定的目录,即 js/main.js 文件所在的目录。当然,你可以通过配置文件修改。
      2、define 定义模块方法只能用在独立的js文件中,不能在页面中直接使用。
      否则会报 Mismatched anonymous define() module 错误。

      3、在代码中require一个文件多次,不会导致浏览器反复加载

      不会,这是 RequrieJS 的优点,即使你反复 require 它,它只加载一次。

      8、require深入

      1、cdn回退
      其支持当CDN加载不正确时,回退加载本地相应的库。我们可以通过require.config达到这个目的:

      1
      2
      3
      4
      5
      6
      7
      8
      requirejs.config({
          paths: {
              jquery: [
                  '//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js',
                  'lib/jquery'
              ]
          }
      });

      2、没有依赖?对象字面量?没问题!
      当你写一个没有任何依赖的模块,并且只是返回一个对象包含一些功能函数,那么我们可以使用一种简单的语法:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      define({
          forceChoke: function() {
       
          },
          forceLighting: function() {
       
          },
          forceRun: function() {
       
          }   
      });

      很简单,也很有用,如果该模块仅仅是功能的集合,或者只是一个数据包。
      3、循环依赖
      在一些情况中,我们可能需要模块moduleA和moduleA中的函数需要依赖一些应用。这就是循环依赖。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      // js/app/moduleA.js
      define( [ "require", "app/app"],
          function( require, app ) {
              return {
                  foo: function( title ) {
                      var app = require( "app/app" );
                      return app.something();
                  }
              }
          }
      );

      4、得到模块的地址
      如果你需要得到模块的地址,你可以这么做……

      1
      var path = require.toUrl("./style.css");

      5、JSONP
      我们可以这样处理JSONP终端:

      1
      2
      3
      4
      5
      require( [
      ], function (data) {
          console.log(data);
      });

      9、r.js压缩

      Require.js 提供一个脚本 r.js ,可以将所有使用到的模块压缩成一个脚本文件,r.js 可以使用 node.js 来执行。

      在压缩模块前,需要写一个配置文件,说明主模块名,压缩后的文件名,哪些模块不要压缩

      没有使用 define 定义的模块都不要压缩,包括 jquery,backbone 等库及其插件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      //build.js
      ({
          baseUrl: '.',
          paths: {
          'jquery': 'empty:',
          'underscore': 'empty:',
          'backbone': 'empty:',
        },
          name: 'main',
          out: 'main.min.js'
      })

      压缩命令:

      1
      node r.js -o build.js

      更多require.js学习链接

js模块化开发——require.js学习总结的更多相关文章

  1. JS模块化开发----require.js

    前言 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了,jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得前 ...

  2. js模块化开发——require.js的用法详细介绍(含jsonp)

    RequireJS的目标是鼓励代码的模块化,它使用了不同于传统<script>标签脚本加载步骤.可以用它回事.优化代码,但其主要的目的还是为了代码的模块化.它鼓励在使用脚本以moudle ...

  3. js模块化开发——require.js的实战写法1

    关于在Require.js使用一个JS插件的问题 我需要在项目中引用一个js控件,这个控件依赖于a.js,b.js,c.js,.....n.js N多个js以及jquery及jquery-ui,各js ...

  4. js模块化开发——require.js的用法

    这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js. 一.为什么要用require.js? 最早的 ...

  5. JS模块化工具require.js教程(一):初识require.js

    随着网站功能逐渐丰富,网页中的js也变得越来越复杂和臃肿,原有通过script标签来导入一个个的js文件这种方式已经不能满足现在互联网开发模式,我们需要团队协作.模块复用.单元测试等等一系列复杂的需求 ...

  6. JS模块化工具require.js教程(二):基本知识

    前一篇:JS模块化工具我们以非常简单的方式引入了requirejs,这一篇将讲述一下requirejs中的一些基本知识,包括API使用方式等 基本API require会定义三个变量:define,r ...

  7. JS模块化开发:使用SeaJs高效构建页面

    一.扯淡部分 很久很久以前,也就是刚开始接触前端的那会儿,脑袋里压根没有什么架构.重构.性能这些概念,天真地以为前端===好看的页面,甚至把js都划分到除了用来写一些美美的特效别无它用的阴暗角落里,就 ...

  8. JS模块化开发(三)——seaJs+grunt

    1.seaJs直接构建存在的问题 由于模块之间的依赖require引用的是模块名,当多个js模块被合并成一个时,会由于找不到模块名而报错 2.seaJs+grunt开发 用到的插件:grunt-cmd ...

  9. Js模块化开发的理解

    Js模块化开发的理解 模块化是一个语言发展的必经之路,其能够帮助开发者拆分和组织代码,随着前端技术的发展,前端编写的代码量也越来越大,就需要对代码有很好的管理,而模块化能够帮助开发者解决命名冲突.管理 ...

随机推荐

  1. mac版MyEclipse的安装及创建web项目

    这两天快被MyEclipse整死了,因为电脑是mac系统的,安装MyEclipse mac破解版时一直是不成功,弄了一天多才行,接着创建web项目HttpServlet在Tomcat发布时总是出现40 ...

  2. wex5 实战 微信6位数字密码输入设计

    微信支付使用是6位数字输入,用wex5能不能制作这种效果呢? 答案是肯定的. 根据网上提供的数字插件,研究源码后,与wex5进行整后修改,便于利用wex5框架优势. 一 效果演示: 弹出密码框 输入 ...

  3. iReport使用教程

    http://www.blogjava.net/keweibo/articles/239492.html 原创出处 http://blog.163.com/liushuo216@126/blog/st ...

  4. JSON串行化

    大多数情况下,我们不会再Javascript中直接创建JSON字符串.而是,创建一些Javascript对象,这些对象和服务器上的.net对象对应.因此,可以在服务器上创建.net实体类,然后串行化成 ...

  5. shell之crontab

    一  crontab高级用法 Crontab 主要是在做排程, 通常一般寫法大概都是如下: 0 0 * * * /usr/local/www/awstats/cgi-bin/awstats.sh 這種 ...

  6. mustache.js基本使用(一)

    作者:zccst 模板已是第二次接触,第一次使用模板记得是在十分系统里渲染页面时使用,当时已做到熟练使用,但实际上仍不知道原因. 再次学习模板已不是从0开始,所以还算顺手,但毕竟还只限于使用,今天继续 ...

  7. HDU 5631 Rikka with Graph

    如果原图不连通,直接输出0. 如果原图连通,删除X条边之后要保证新图连通,再看数据是n+1条边-->因此,最多只能删去两条边. 因为n=100,可以枚举进行验证,枚举删去每一条边是否连通,枚举删 ...

  8. poj3190区间类贪心+优先队列

    题意:每个奶牛产奶的时间为A到B,每个奶牛产奶时要占用一间房子,问n头奶牛产奶共需要多少房子,并输出每头奶牛用哪间房子 分析:这题就是一个裸的贪心,将奶牛按开始时间进行排序即可,但考虑一下数据范围,我 ...

  9. LPC1788的内部EEPROM使用

    Lpc1788内置有eeprom 使用代码 #ifndef __E2PRONINCHIP_H_ #define __E2PROMINCHIP_H #include "common.h&quo ...

  10. LPC1768的SPI通讯

    SPI是一种全双工串行接口,可处理多个连接到指定总线上的主机和从机.在数据传输过程中总线上只能有一个主机和一个从机通信.在数据传输中,主机总是会向从机发送一帧8到16个位的数据,而从机也总会向主机发送 ...