requireJS 学习笔记

参考123

一、关于使用requireJS

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>

这样的时候。主要问题有两个。
第一是文件越多,因为浏览器同时加载文件有限(6个),所以会造成css,图片之类的加载缓慢。浏览器就会停止响应。
第二是依赖关系,因为互相依赖,所以需要确保顺序,当之间关系复杂,就更加难以处理。

requireJS就是为了这个,异步加载,处理依赖关系。

二,下载安装

http://requirejs.org/下载,放到工作目录内js文件夹,创建下面两个文件

index.html:

<span class="dec">&lt;!DOCTYPE html&gt;</span>
<span class="tag">&lt;html&gt;</span>
    <span class="tag">&lt;head&gt;</span>
        <span class="tag">&lt;script</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"text/javascript"</span> <span class="atn">src</span><span class="pun">=</span><span class="atv">"js/require.js"</span><span class="tag">&gt;&lt;/script&gt;</span>
        <span class="tag">&lt;script</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"text/javascript"</span><span class="tag">&gt;</span><span class="pln">
                             require</span><span class="pun">([</span><span class="str">"a"</span><span class="pun">]);</span>
        <span class="tag">&lt;/script&gt;</span>
    <span class="tag">&lt;/head&gt;</span>
    <span class="tag">&lt;body&gt;</span>
      <span class="tag">&lt;span&gt;</span><span class="pln">body</span><span class="tag">&lt;/span&gt;</span>
    <span class="tag">&lt;/body&gt;</span>
<span class="tag">&lt;/html&gt;</span>

a.js:

<span class="pln">define</span><span class="pun">(</span><span class="kwd">function</span><span class="pun">(){</span>
    <span class="kwd">function</span><span class="pln"> fun1</span><span class="pun">(){</span><span class="pln">
                 alert</span><span class="pun">(</span><span class="str">"it works"</span><span class="pun">);</span>
    <span class="pun">}</span><span class="pln">

    fun1</span><span class="pun">();</span>
<span class="pun">})</span>

运行看看,弹出来”it works”,第一步完成啦~

二、进一步了解依赖

我们这里把index.html里边的

<span class="pln">  require</span><span class="pun">([</span><span class="str">"a"</span><span class="pun">]);</span>

改成

<span class="kwd">require</span><span class="pun">([</span><span class="str">"js/a"</span><span class="pun">],</span><span class="kwd">function</span><span class="pun">(){</span><span class="pln">
    alert</span><span class="pun">(</span><span class="str">"load finished"</span><span class="pun">);</span>
<span class="pun">})</span>

这里再试试,除了’it works’ 还有’load finished’,这样的顺序出现。

这里可以看到require 里边的中括号实际是一个数组,当你有许多个依赖时,这里就可以当作数组加载依次加载。但是就算只有一个依赖,也需要写成数组。

后边的function就是回调函数,就是当依赖加载结束,执行里边的函数。

比如我现在依赖三个模块jquery、underscore和backbone ,可以这样写:

require(['js/jquery', 'js/funnjs','js/underscore', 'js/backbone'], function ($       , funn,_, Backbone){
  // some code here
});

这里边前边是依赖数组。后边那些’$’ 、’_’其实是指前边依赖加载完毕的返回对象。比如funnjs里有个return a; 那么在下边的函数内就可以用语句funn.a  来使用返回对象。

在这里有一点,就是”js/jquery’是指’js/jquery.js’.这里是把扩展名忽略了。

三、关于加载文件

其实像用’js/jquery’这样很麻烦,可以使用

<span class="kwd">require</span><span class="pun">.</span><span class="pln">config</span><span class="pun">({</span><span class="pln">
    paths </span><span class="pun">:</span> <span class="pun">{</span>
        <span class="str">"a"</span> <span class="pun">:</span> "js/a"   
    <span class="pun">}</span>
<span class="pun">})</span>
<span class="kwd">require</span><span class="pun">(</span><span class="str">"a"</span><span class="pun">],</span><span class="kwd">function</span><span class="pun">(</span><span class="pun">){</span><span class="pln">
    $</span><span class="pun">(</span><span class="kwd">function</span><span class="pun">(){</span><span class="pln">
        alert</span><span class="pun">(</span><span class="str">"load finished"</span><span class="pun">);</span>  
    <span class="pun">})</span>
<span class="pun">})</span>

也可以使用远程文件

<span class="kwd">require</span><span class="pun">.</span><span class="pln">config</span><span class="pun">({</span><span class="pln">
    paths </span><span class="pun">:</span> <span class="pun">{</span>
        <span class="str">"jquery"</span> <span class="pun">:</span> <span class="pun">[</span><span class="str">"http://libs.baidu.com/jquery/2.0.3/jquery"</span><span class="pun">],</span>
        <span class="str">"a"</span> <span class="pun">:</span> <span class="str">"js/a"</span>   
    <span class="pun">}</span>
<span class="pun">})</span>
<span class="kwd">require</span><span class="pun">([</span><span class="str">"jquery"</span><span class="pun">,</span><span class="str">"a"</span><span class="pun">],</span><span class="kwd">function</span><span class="pun">(</span><span class="pln">$</span><span class="pun">){</span><span class="pln">
    $</span><span class="pun">(</span><span class="kwd">function</span><span class="pun">(){</span><span class="pln">
        alert</span><span class="pun">(</span><span class="str">"load finished"</span><span class="pun">);</span>  
    <span class="pun">})</span>
<span class="pun">})</span>

用paths还有一个功能就是配置多个地址,如果一个不能加载,就立刻换下一个。

<span class="kwd">require</span><span class="pun">.</span><span class="pln">config</span><span class="pun">({</span><span class="pln">
    paths </span><span class="pun">:</span> <span class="pun">{</span>
        <span class="str">"jquery"</span> <span class="pun">:</span> <span class="pun">[</span><span class="str">"http://libs.baidu.com/jquery/2.0.3/jquery"</span><span class="pun">,</span> <span class="str">"js/jquery"</span><span class="pun">],</span>
        <span class="str">"a"</span> <span class="pun">:</span> <span class="str">"js/a"</span>   
    <span class="pun">}</span>
<span class="pun">})</span>

四、关于main.js

像这样的配置,如果每个html内都有,无疑是浪费的。所以需要把require.config做成全剧共部分。在js文件夹内创建main.js:

<span class="kwd">require</span><span class="pun">.</span><span class="pln">config</span><span class="pun">({</span><span class="pln">
    paths </span><span class="pun">:</span> <span class="pun">{</span>
        <span class="str">"jquery"</span> <span class="pun">:</span> <span class="pun">[</span><span class="str">"http://libs.baidu.com/jquery/2.0.3/jquery"</span><span class="pun">,</span> <span class="str">"js/jquery"</span><span class="pun">],</span>
        <span class="str">"a"</span> <span class="pun">:</span> <span class="str">"js/a"</span>   
    <span class="pun">}</span>
<span class="pun">})</span>

<span class="tag">&lt;script</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"text/javascript"</span> <span class="atn">src</span><span class="pun">=</span><span class="atv">"js/require.js"</span><span class="tag">&gt;&lt;/script&gt;</span>

更换成

<span class="tag">&lt;script</span> <span class="atn">data-main</span><span class="pun">=</span><span class="atv">"js/main"</span> <span class="atn">src</span><span class="pun">=</span><span class="atv">"js/require.js"</span><span class="tag">&gt;&lt;/script&gt;</span>

这里加入了data-main属性。这里指定的js将会在require.js加载完毕运行。每个页面就可以不用写require.config,直接使用全局设定。

五,例子1

说真的我当时看到这些,觉得,这些有啥用啊。。就有了以下的例子

index.html

&lt;!DOCTYPE html&gt;
  &lt;html&gt;
    &lt;head&gt;
       &lt;script data-main="js/main" src="js/require.js"&gt;&lt;/script&gt;
       &lt;script type="text/javascript"&gt;
          require(["js/a.js","js/b.js"],function(){
            funa();
            funb();
          })
       &lt;/script&gt;
   &lt;/head&gt;
   &lt;body&gt;
     &lt;span&gt;body&lt;/span&gt;
   &lt;/body&gt;
&lt;/html&gt;

js/a.js

 function funa(){
    alert("a works");
}

js/b.js

 function funb(){
    alert("b works");
}

以上。

就可以在主函数内调用两个文件中的函数。

另外,RequireJS默认并没有保证一定会在页面加载完毕执行的。如果需要在加载完毕后加载。就需要一个官方模块。在官网下载domReady模块.把这个js放到js文件夹内。

&lt;script&gt; 
    require(["domReady!", "js/a.js", "js/b.js"], function() { 
	    	 funa(); 
	    	 funb(); 
	    }); 
&lt;/script&gt;

这样就能能达到目的了。

六、关于模块化设计

在传统JavaScript中,使用全局变量过于容易。但是有时候却并不需要这样,因为命名空间会过于庞大复杂。所以可以通过 AMD 规范将一个模块内的变量仅自己使用,避免声明了全局变量。使用的时候,比如b依赖a,那么c访问b中的变量,用a.b来实现。

student.js
 define(function(){ 
	 return { 
	    createStudent: function(name, gender){ 
	    	 return { 
	    		 name: name, 
	    		 gender: gender 
	    	 }; 
	    } 
	 }; 
 });
class.js
 define(function() { 
 var allStudents = []; 
        return { 
            classID: "001", 
            department: "computer", 
            addToClass: function(student) { 
            allStudents.push(student); 
            }, 
            getClassSize: function() { 
            return allStudents.length; 
            } 
        }; 
     } 
 );
主程序
require(["js/student", "js/class"], function(student, clz) { 
   clz.addToClass(student.createStudent("Jack", "male")); 
   clz.addToClass(student.createStudent("Rose", "female")); 
   console.log(clz.getClassSize());  // 输出 2 
   console.log(clz.classID) ; //输出001
});

是的,就输出一个2。还有一个班级号。

这里的clz就是指js/class  return的对象组。这个看起来比较简单明了。现在复杂一点。

依赖 student 和 class 模块的 manager 模块,manager.js
 define(["js/student", "js/class"], function(student, clz){ 
  return { 
    addNewStudent: function(name, gender){ 
      clz.addToClass(student.createStudent(name, gender)); 
    }, 
    getMyClassSize: function(){ 
       return clz.getClassSize(); 
    } 
   }; 
 });
新的主程序
 require(["js/manager"], function(manager) { 
    manager.addNewStudent("Jack", "male"); 
    manager.addNewStudent("Rose", "female"); 
    console.log(manager.getMyClassSize());// 输出 2 
 });

一样输出2.

这里就多了这么一句

clz.addToClass(student.createStudent(name, gender));

其实就是用前缀来区分命名空间。

然后。

暂时告一段落。。。

 


 

 

 

 

此条目发表在前端分类目录。将固定链接加入收藏夹。