RequireJs的使用详解


Posted in Javascript onFebruary 19, 2017

一、为什么使用RequireJS?

  <script src="a.js"></script>
<script src="b.js"></script>

<script src="c.js"></script>

上述多个js文件加载的时候,浏览器会停止网页渲染(JS阻塞浏览器渲染),加载文件越多,网页失去响应的时间就会越长;另外各文件的依赖关系很难管理。

RequireJs的作用:

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

(2)管理模块之间的依赖性,便于代码的编写和维护。

(3)定义了一个作用域来避免全局名称空间污染。

二、require.js的加载

1.从官网下载最新版本的require,放在js目录下,使用script引入页面:

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

为了不阻塞页面渲染,可以把它放在HTML的最底部或改为如下方式:

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

async属性表明该文件需异步加载(defer属性兼容IE)。

2.加载页面逻辑代码:

假定代码文件是main.js,也放在js目录下,则用如下几种方式引入:

方式1:

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

data-main属性指定网页程序的主入口,这个文件会第一个被requirejs加载。requirejs默认所依赖的资源都是js,所以可以把main.js简写成main。

方式2:

在加载require.js后,通过requirejs加载config配置文件(如有),最后加载主模块:

require([‘configUrl'],function () { //config.js必须通过requirejs加载才能注册
 require([moduleAName],function(moduelA){
 //逻辑代码
 })
});

三、主模块的写法

// main.js
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){


// some code here

});

require()函数接受两个参数,第一个参数是一个数组,表示当前模块所依赖的模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该回调函数,从而在回调函数内部就可以使用这些模块(被依赖的模块有return的值)。

require()异步加载moduleA,moduleB和moduleC,浏览器不会失去响应;它指定的回调函数,只有当前面依赖的模块全部下载并执行对应的回调之后,才会运行。

四、模块的配置

require.config()方法可以定义模块的路径,并以短模块名的形式进行依赖的定义。该方法可以写在每个主模块(main.js)的前面,配合主模块一起使用。

参数是一个对象,这个对象的paths属性指定各个模块的加载路径。paths可以配置多个路径,如果远程cdn库没有加载成功,则加载本地的库。

如果不定义模块的配置,则在主模块中的依赖需要写完整路径。

在每个页面按需配置路径:

require.config({  //注册模块的配置,供后面的代码使用

baseUrl: '/js/', 
 paths: {
 
"jquery":”cdnUrl”, "Jquery/jquery-1.12.0.min"
  "fixheight": "login/fixheight"
 }
 });
 require(['jquery', 'fixheight'], function ($, fixHeight) {
 ...other code; 
 fixHeight.init();
});

或者将config配置作为一个单独的js文件,然后

require([“configJsUrl”],function(){  //需要在main文件中通过require先异步加载模块配置
 require([‘ModuleName'],function(Name){
 …other code
 })
})

为了避免每个页面都要嵌套require,还可以用如下方式:

先创建单独的config.js文件:

require.config({ //注册模块的配置,供后面的代码使用
 baseUrl: "/js/app/", //其他依赖都是对于此位置的相对路径
 // 路径配置
 paths: {
underscore: 'vender/underscore.min',   backbone:'vender/backbone.min'
 jquery: ‘cdnUrl','vender/jquery/jquery-1.12.0.min',
 “模块短名”:”相对于baseUrl的路径地址,省略模块文件的后缀.js”
 },
 // 非AMD模式编写的类库需要重新配置
 shim: {
 underscore: {
  exports:'_'
 },
 backbone(短模块名仍需要定义路径): {
  exports: 'Backbone',  
//类库输出的变量名,表明这个模块被外部调用时的名称
  deps:['jquery','underscore'] //该模块的依赖
 }
 },
 urlArgs: "bust=" + document.getElementById('publishDate').attributes['value'].value
//js资源的参数,控制版本刷新缓存
});
define([ 'marionette'], function () { }); //仍是会被执行的js代码,会依次加载需要的模块

然后通过如下方式使用:

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

通过主入口直接将模块配置注册到requirejs命名空间中,页面中后续的require方法无需再注册,可以直接使用短模块名进行依赖加载。

如果没有显式指定config及data-main,则默认的baseUrl为加载RequireJS的HTML页面所在目录。如果指定了data-main而没有在config中指定根路径,则该路径被设为baseUrl。

若想避开"baseUrl + paths"的解析过程,而是直接指定加载某一个目录下的脚本。可以这样做:如果一个module ID符合下述规则之一,其ID解析会避开常规的"baseUrl + paths"配置,而是直接将其加载为一个相对于当前HTML文档路径的脚本:

•    以 ".js" 结束.

•    以 "/" 开始.

•    包含 URL 协议, 如 "http:" or "https:".

eg. require(['/www/js/app/vender/underscore.min.js'], function (_) {…})

require.js要求,每个模块是一个单独的js文件。加载多个模块就会发出多次HTTP请求,影响网页的加载速度。因此require.js提供了一个优化工具(r.js),当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数,但又需要和缓存之间进行取舍。

六、AMD模块的写法

require.js加载的模块,必须按照AMD的规定来写。即模块必须采用特定的define()函数来定义,通常返回一个对象,该对象具有供别的模块使用的方法或属性;或只执行相关逻辑而无输出。

七、require.js的相关插件

text插件,允许require.js异步加载txt、css或html等文本资源供js使用,而不需要在script内构建Html字符串。

define(['text!components/multiple/template.html', 'image!cat.jpg'],
 function(template,cat){
 $('body').append($(template));
 document.body.appendChild(cat);
 }
);

注意:

模块的依赖既可以通过[]引入,也可以在回调函数里通过require()方法引入,效果一样。因为define方法会通过正则先扫描回调函数中require方法的依赖并下载,然后才执行该回调函数。但此时需要传入依赖require本身,否则会报错:

define(function(require){
 var helper=require(‘helpModuleUrI');//也会提前加载该依赖
 …
})

多个模块先后多次依赖同一个模块时,该模块只会被下载并初始化一次,之后require会保持对其的引用供别的模块再次使用。

区分require方法的执行和回调的执行:

require('config',callBack1);
require('b',callBack2);
// 两个require方法会立即执行,但callBack的执行顺序不确定,取决于下载的顺序。
//不同于以下代码,会严格按顺序执行
require('config',function(){
 require('b',callBack2)
})

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
IE与Firefox下javascript getyear年份的兼容性写法
Dec 20 Javascript
JavaScript中的Screen屏幕对象
Jan 16 Javascript
基于JQuery 的消息提示框效果代码
Jul 31 Javascript
JavaScript判断变量是否为空的自定义函数分享
Jan 31 Javascript
自定义百度分享的分享按钮
Mar 18 Javascript
jQuery mobile 移动web(4)
Dec 20 Javascript
jQuery实现简单的图片查看器
Sep 11 Javascript
浅谈js数据类型判断与数组判断
Aug 29 Javascript
node.js版本管理工具n无效的原理和解决方法
Nov 24 Javascript
JavaScript数组的5种迭代方法
Sep 29 Javascript
解决echarts vue数据更新,视图不更新问题(echarts嵌在vue弹框中)
Jul 20 Javascript
Vue自定义铃声提示音组件的实现
Jan 22 Vue.js
Vue.js -- 过滤器使用总结
Feb 18 #Javascript
JS打开摄像头并截图上传示例
Feb 18 #Javascript
Android中Okhttp3实现上传多张图片同时传递参数
Feb 18 #Javascript
AngularJS表单提交实例详解
Feb 18 #Javascript
JS实现控制图片显示大小的方法【图片等比例缩放功能】
Feb 18 #Javascript
JS实现数组去重复值的方法示例
Feb 18 #Javascript
bootstarp modal框居中显示的实现代码
Feb 18 #Javascript
You might like
PHP中preg_match正则匹配中的/u、/i、/s含义
2015/04/17 PHP
[原创]PHP global全局变量经典应用与注意事项分析【附$GLOBALS用法对比】
2019/07/12 PHP
php模拟实现斗地主发牌
2020/04/22 PHP
js中eval()函数和trim()去掉字符串左右空格应用
2013/02/02 Javascript
jQuery方法简洁实现隔行换色及toggleClass的使用
2013/03/15 Javascript
使用js正则控制input标签只允许输入的值
2013/07/29 Javascript
jquery等宽输出文字插件使用介绍
2013/09/18 Javascript
JavaScript转换二进制编码为ASCII码的方法
2015/04/16 Javascript
浅谈JS中json数据的处理
2016/06/30 Javascript
详解百度百科目录导航树小插件
2017/01/08 Javascript
Web 开发中Ajax的Session 超时处理方法
2017/01/19 Javascript
脚本div实现拖放功能(两种)
2017/02/13 Javascript
微信小程序如何获知用户运行小程序的场景教程
2017/05/17 Javascript
详解Vue 非父子组件通信方法(非Vuex)
2017/05/24 Javascript
js弹性势能动画之抛物线运动实例详解
2017/07/27 Javascript
Vue 前端实现登陆拦截及axios 拦截器的使用
2019/07/17 Javascript
[01:14:12]2018DOTA2亚洲邀请赛4.7 总决赛 LGD vs Mineski 第二场
2018/04/09 DOTA
python获取文件后缀名及批量更新目录下文件后缀名的方法
2014/11/11 Python
python动态参数用法实例分析
2015/05/25 Python
使用EduBlock轻松学习Python编程
2018/10/08 Python
75条笑死人的知乎神回复,用60行代码就爬完了
2019/05/06 Python
Python 多个图同时在不同窗口显示的实现方法
2019/07/07 Python
详解pandas apply 并行处理的几种方法
2021/02/24 Python
css3打造一款漂亮的卡哇伊按钮
2013/03/20 HTML / CSS
HTML5的革新 结构之美
2011/06/20 HTML / CSS
HTML5之SVG 2D入门2—图形绘制(基本形状)介绍及使用
2013/01/30 HTML / CSS
HTML5地理定位实例
2014/10/15 HTML / CSS
世界最大的票务市场:viagogo
2017/02/16 全球购物
分解成质因数(如435234=251*17*17*3*2,据说是华为笔试题)
2014/07/16 面试题
护理专业推荐信
2013/11/07 职场文书
新闻报道策划方案
2014/06/11 职场文书
社区反邪教工作方案
2014/06/16 职场文书
国际经济与贸易专业求职信
2014/07/10 职场文书
搞笑的爱情检讨书
2014/10/01 职场文书
县长“四风”对照检查材料思想汇报
2014/10/05 职场文书
天堂的孩子观后感
2015/06/11 职场文书