Require.js

来源:互联网 发布:电脑时间提醒软件 编辑:程序博客网 时间:2024/04/28 15:40
随着网址功能的日渐丰富,页面的 js 也变的越来越复杂和臃肿,原本通过 script 标签来导入 js 文件的方式已经不能满足我们的开发需求了,我们需要团队合作、模块复用、单元测试等等一系列复杂的需要,所以 Require.js 就应运而出了。  RequireJS 是一个非常小巧的 javascript 模块载入框架,是 AMD(Asynchronous Module Definition,异步模块加载机制)规范最好的实现之一。最新版的 requireJS 压缩后只有 14k,堪称非常轻量。它还同时可以和其他的框架协调工作,使用 requireJS 必将使我们的前端代码质量得以提升。 

RequireJS 的好处
Requires 官方网站这样说的: (RequireJS is a JavaScript fileand module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.)RequireJS 是一个 JavaScript 模块加载器。它非常适合在浏览器中使用,但它也可以用在其他脚本环境, 就像 Rhino and Node. 使用 RequireJS 加载模块化脚本将提高代码的加载速度和质量。

RequireJS 的初识~~不胜风情
首先我们先使用一个普通的页面来看看:

<!doctype html><html>  <head>   <meta charset="UTF-8">   <title></title>   <script type="text/javascript" src="js/test01.js"></script>  </head>  <body>       <h1>Hello requireJS</h1>  </body> </html> 

test01文件:

(function(){        function fn1() {           alert("Hello requirejs~~~");         };     fn1(); })(); 

使用闭包写了一个最简单的函数,弹出一句话,我们使用闭包的好处就是避免全局变量的出现,这样就防止了全局变量的污染。 在这段代码中,我们导入了一个 test01.js 文件,当我们打开页面时,引入的test01.js 文件加载成功;
这里写图片描述
我们发现页面上的内容没有输出,js 弹出框在等待用户的点击后,页面才会继续运行,这样的结果我们不能接受,因为 js 一般和页面的加载关,我们应该让页面继续加载,js 执行自己就行了,但是现在阻塞住了页面的继续加载,如果某个 js 文件报错,很有可能导致页面的正常加载和运行,这是我们不能接受的。
那么如果我们使用 requireJS 呢?首先我们来演示下,大家来看看:

<!DOCTYPE html> <html> <head>      <meta charset="UTF-8">      <title></title>      <script   type="text/javascript"src="js/require2.1.11.js">     </script>      <script type="text/javascript">          require(["js/test02"]);      </script>  </head>  <body>       <h1>Hello requireJS</h1>  </body>  </html>

test02.js 文件:

define(function(){        function fn1() {           alert("Hello requirejs~~~");      fn1(); }); 

我们看出,首先页面上不再导入 test02.js,只是导入了 requireJS,其次在 javascript 中我们使用 require()方法,在其中传递了一个数组的参数,实参为我们要导入的 js 文件的【路径+文件名称(后缀名可带可不带,不建议写,因为后面的网络访问时不能写,为了保持一致,不建议带)】 ,这样就完成了 requireJS 的使用,那么运行效果如何呢?
这里写图片描述

我们发现此时的页面加载已经完成了,并不像前面我们传统的一样在等待 js 运行完成后页面再加载,而是页面加载完成后才运行 js 代码,这样在运行效率上就大大的提高了。
这里写图片描述

回过头来我们看看 test02.js,我们发现和 test01.js 写法不同的是闭包—()();的写法改成了 define();在 define 函数中传递匿名函数完成操作,这个变化不大,大家应该很好能接受。
基本 API
requireJS 会定义三个变量:define、require、requirejs。

        1 require === requirejs,一般使用 require 更简短。         2 define 从名字就可以看出这个 api 是用来定义一个模块。         3 require 加载依赖模块,并执行加载完后的回调函数。 

前面我们写的 test02.js:

define(function(){        function fn1() {           alert("Hello requirejs~~~");      }        fn1(); }); 

就是使用 define 来定义了一个模块,然后使用 require 来引用

<script type="text/javascript">      require(["js/test02"]);//参数为一个数组 </script> 

来加载该模块(注意 require 中的依赖是一个数组,即使只有一个依赖,你也必须使用数组来定义),requir API 的第二个参数是 callback,一回调函数,是用来处理加载完毕后的逻辑,如:

require(["js/test02.js"],function(){      alert("js加载完成"); });

当所有的模块都加载完成后就会触发这个函数。同样存在了第三个参数,也是一个callback 函数,这个是来处理加载失败后的情况的,如:

require(["js/test03"],function(){              alert("js加载完成");         },function(){          //当没有加载成功后就会触发          //失败的话,在这个函数中处理          alert("加载失败~~~"); });

此时 test03.js 不存在,页面肯定加载不成功,所以会触发第三个参数。
加载网络文件
之前的例子中加载模块都是本地 js,但是大部分情况下网页需要加载的 JS 可能来自本地服务器、其他网站或 CDN,这样就不能通过这种方式来加载了,我们以加载一个 jquery 库为例:
*//百度cdn公共库jQuery地址:
http://apps.bdimg.com/libs/jquery/2.1.1/jquery.js
//jQuery官方地址:
https://code.jquery.com/jquery-3.1.1.js*

//注意:网络上去取时不能加后缀,否则取不到 require.config({          paths : {   //为网络上的库去一个名字:jquery                               "jquery" : ["https://code.jquery.com/jquery-3.1.1"]  } });  // require(["jquery","js/test01","js/test02"],function(){              alert("页面加载成功~~");             },function(){              alert("页面加载失败~~") }); 

在取网络上的文件时注意:
1、 config 方法的参数是一个对象
2、 paths 的值也是一个对象
3、 当我们为网络上的库取名字是任意,但是建议取有意义的名字,别人可以通过名称知道你的网络资源是什么资源
4、 库的值是一个数组,意味着可以多个同时写,防止网络异常取不到
5、 特别注意:网络资源路径不能带后缀名,否则取不到
6、 我们也可以先让去网络中去取,如果取不到,再在本地取,减轻本地服务的压力(属于项目优化)

require.config({  paths : {   //这样配置,减轻本地服务器的压力   "jquery" :["https://code.jquery.com/jquery3.1.1.js",  "js/jquery-1.8.3"]  } });  require(["jquery","js/test01","js/test02"],function(){              alert("页面加载成功~~"); },function(){  alert("页面加载失败~~") }); 

同样我们也可以将本地的配置到 paths 中:

require.config({  paths : {   //这样配置,减轻本地服务器的压力   "jquery" : ["https://code.jquery.com/jquery-3.1.1","js/jquery-1.8.3"],   //将本地的js文件同样配置,之后引用   "test01" : ["js/test01"],   "test02" : ["js/test02"]  } });  // require(["jquery","test01","test02"],function(){  alert("页面加载成功~~"); },function(){  alert("页面加载失败~~") }); 

全局配置
上面的例子中重复出现了 require.config 配置,如果每个页面中都加入配置,必然显得十分不雅,requirejs 提供了一种叫”主数据”的功能,我们首先创建一个 main.js:

require.config({  paths : {   //这样配置,减轻本地服务器的压力   "jquery" : ["https://code.jquery.com/jquery-3.1.1","js/jquery-1.8.3"],   //将本地的js文件同样配置,之后引用   "test01" : ["js/test01"],   "test02" : ["js/test02"]  } }); 

然后再页面中使用下面的方式来使用 requirejs:

<script type="text/javascript" src="js/require2.1.11.js" ></script> <script type="text/javascript" src="js/main.js" ></script> <script type="text/javascript">          require(["jquery","t1","t2"],function(){       alert("页面加载成功~~");      },function(){       alert("页面加载失败~~")  });   </script> 

在官方提供了一种基于标签属性的方式:

<script data-main="js/main" src="js/require2.1.11.js" ></script> 

将所有的配置和导入 js 都放在了 main.js 中,这样在页面只要这样一个标签就行了。
第三方模块
通过 require 加载的模块一般都需要符合 AMD 规范即使用 define 来申明模块,但是部分时候需要加载非 AMD 规范的 js,这时候就需要用到另一个功能:shim,shim 解释起来也比较难理解,shim 直接翻为”垫”,其实也是有这层意思的,目前我们主要用在两个地方 非 AMD 模块输出,将非标准的 AMD 模块”垫”成可用的模块,例如:在老版本的jquery
中,是没有继承 AMD 规范的,所以不能直接 require[“jquery”],这时候就需要 shim,比如我要是用 underscore 类库,但是他并没有实现 AMD 规范,那我们可以这样配置`

require.config({         shim: {                 "underscore" : {             }     } }) 

这样配置后,我们就可以在其他模块中引用 underscore 模块: require

require(["underscore"], function(_){         _.each([1,2,3], alert);     }) 

插件形式的非 AMD 模块,我们经常会用到 jquery 插件,而且这些插件基本都不符合AMD 规范,比如 jquery.form 插件,这时候就需要将form 插件”垫”到 jquery 中:

require.config({         shim: {                  "underscore" : {                          exports : "_";                  "jquery.form" : {                         deps : ["jquery"]                      }             } })

也可以简写为:

require.config({         shim: {                 "underscore" : {                         exports : "_";                     },                 "jquery.form" : ["jquery"]             } }) 

这样配置之后我们就可以使用加载插件后的 jquery 了

require.config(["jquery", "jquery.form"], function($){     $(function(){             $("#form").ajaxSubmit({...});         }) }) 

其他内容
在回调函数中,我们可以再对应的参数得到加载的 js 对象,如第一个就是 jQuery 对象,第二个和第三个我们自己的 js 中没有返回对象,所以为 undefined。

<script type="text/javascript" src="js/require2.1.11.js" ></script> <script type="text/javascript" src="js/main.js" ></script> <script type="text/javascript">      require(["jquery","t1","t2"],function($,t1,t2){           //我们在回调函数中可以传递参数,这些参数就是require方法中的js对象,如jQuery对象                  alert($("body").html());               },function(){                alert("页面加载失败~~")               });   </script> 

还是就是在 define 函数中同样可以传递一个数组参数,这个数组参数就是在前面我们已经 config 过的 js 库或者我们本地的 js 文件,如:

//将要使用的库可以再这儿引入 define(["jquery"],function($){        function fn1() {           alert("Hello requirejs~~~***");          }          //alert($(window).scrollTop());          fn1(); }); 

这样我们在 define 中制作 jQuery 的插件的话,就可以直接使用了

0 0