首页 > 网站 > WEB开发 > 正文

Require.js

2024-04-27 15:06:30
字体:
来源:转载
供稿:网友
随着网址功能的日渐丰富,页面的 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 的插件的话,就可以直接使用了


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表