1. 认识
GitHub 自己练习的代码
RequireJs 是一个 js 文件,用于 模块化的管理 js 文件,属于 AMD 规范的一种实现;可以 提升速度 和 提高代码质量;详情见官网:http://requirejs.org/
2. 使用
2.1 入口
配置 require.js 的 js 文件时,增加 data-main 属性,即为 js 的入口;
Note:data-main 所指定的 js 文件是 异步加载的,所以在页面指定多个 js 时,即便是放在 data-main 的下方也无法保证 加载的顺序;
对于入口文件的选择:
① 如果项目是将一个页面分为 多个 layout(tiles 布局,如 general:页面的整体,其他各个layout 填充该 页面;header:页面的头部,填充 genneral;footer:页面的尾部,填充 genneral;main:页面的主体,不同的页面分别创建,填充 general 等),可以在 genneral页面 引入配置文件;而在 main 页面 引入 各个页面的 js ;这样就可以保证 配置文件在 各个页面的 js 之前加载,就可以在 main 页面的 js 中 使用 配置文件中的配置;
② 如果并没有采用这种布局,那么不同 jsp 页面的 入口文件就使用 各个页面的 js 文件 ,如果要使用配置文件 定义新的模块,则可以在 define 引用的模块数组中加入 配置文件的js,然后加入配置文件中已配置的 js 名,在需要使用的时候,再使用 require 加载 配置文件中的 js 名,否则的话,无法引用到;示例如下:
定义公共util.js 模块 ,配置文件使用下方的 main.js
/** * Created by xlch on 2016/12/27. *///这里会使用到配置文件中配置的 jquery,所以依次引用 配置文件js,jquery//这里虽然引用了 main 模块,但是其中只是声明了 jquery,要调用该模块仍然需要常规的 require 或者 define//这里引用的 jquery 并不存在于js/lib/jquery 路径下,而是配置在 man.js 中,所以还需要下面的 requiredefine(['require','module','../main', 'jquery'],function (require,module) { //这里才真正的加载到 jquery;而且 jquery 必须定义在 define 的模块数组中 var $ = require("jquery"); var utils = {}; utils.quick = { click:function (method,node) { var list = null; if (node) { list = $(node).find("[data-click]"); }else { list = $("[data-click]"); } list.on("click",function (eventObject) { var click = $(this).data("click"); if (click && method[click]) { return method[click].apply(this,[eventObject]); } }); }, offClick:function (method, node) { if (node) { $(node).find('[data-click]').off('click'); }else { $('[data-click]').off('click'); } } }; return utils;});入口文件 栗子:
<script src="${ctx}/js/require.js" data-main="${ctx}/js/app/home"></script>2.2 requirejs 配置文件
常用配置属性
baseUrl: 所有模块查找的根路径,
★ 如果未设置 baseUrl 参数,未使用 data-main 属性,则 baseUrl 的默认值 为 加载 require.js 的 HTML 页面 的 位置;
★ 如果未设置 baseUrl 参数,使用了 data-main 属性,那么 baseUrl 为 data-main 的 路径;
paths:在 baseUrl 下 不能直接发现的 模块名,则使用该选项映射路径,例如含有多级目录,或者在baseUrl 的上级目录;不需要 .js 后缀;
bundles:
shim:用于配置 不兼容的模块,即没有使用 define() 声明 依赖 并且 没有设置一个 模块名的 传统型 脚本;例如 backbone.js;
Note :shim配置仅设置了代码的依赖关系,想要实际加载shim指定的或涉及的模块,仍然需要一个常规的require/define调用。设置shim本身不会触发代码的加载。
其下有两个主要参数:
★ deps :用于声明依赖,数组的形式
★ exports:定义一个模块的名称,作为该 js 的全局引用
那些仅仅作为 jQuery 或者 Backbone 的插件存在,而不用导出任何模块变量的 模块,可以简单配置为依赖的数组;
requirejs.config({ shim: { 'jquery.colorize': ['jquery'], 'jquery.scroll': ['jquery'], 'backbone.layoutmanager': ['backbone'] }});waitSeconds:加载 js 等待的 最长时间,超时则放弃加载,默认时间为 7秒
配置文件栗子:
main.js:
/** * Created by xlch on 2016/12/27. */require.config({ //所有模块查找的根路径 baseUrl: 'js/lib', //目的是将繁琐的引用名称简化,只需要 require(['jquery'],function(){})即可 //路径是相对于 baseUrl 的路径 paths: { "jquery":'jquery/jquery-3.1.1.min', }, // 配置非 amd 规范的 js ,增加依赖 和 输出名称 shim: { // 'backbone':{ depts:['jquery','underscore'], exports:'Backbone' }, 'underscore':{ exports:'_' }, }, //加载 js 等待的 最长时间,超时则放弃加载,默认时间为 7秒 waitSeconds: 30, //main.js 之后加载的 js 的末尾添加后缀,防止缓存,但是生产环境需要去掉 // urlArgs: "bust=" + (new Date()).getTime(), // 应用级别的参数,通过 module.config() 使用,未解 config:{ 'name':{ na:'xlch' }, },});2.3 define
define 用于定义一个 模块 ,定义的模块可以通过 require 调用;这里注意一定要将 结果返回,无论是对象还是函数; 因为 define 定义的模块是给 require 调用的;这样 define 就可以 被外部的其他 模块(module)捕捉到,即可以利用该模块;
例如上面定义一个公共的 util 模块,见上面的示例代码 util.js;
再copy 一下,使用上面的 main.js:
/** * Created by xlch on 2016/12/27. *///这里会使用到配置文件中配置的 jquery,所以依次引用 配置文件js,jquery//这里虽然引用了 main 模块,但是其中只是声明了 jquery,要调用该模块仍然需要常规的 require 或者 define//这里引用的 jquery 并不存在于js/lib/jquery 路径下,而是配置在 man.js 中,所以还需要下面的 requiredefine(['require','module','../main', 'jquery'],function (require,module) { //这里才真正的加载到 jquery;而且 jquery 必须定义在 define 的模块数组中 var $ = require("jquery"); var utils = {}; utils.quick = { click:function (method,node) { var list = null; if (node) { list = $(node).find("[data-click]"); }else { list = $("[data-click]"); } list.on("click",function (eventObject) { var click = $(this).data("click"); if (click && method[click]) { return method[click].apply(this,[eventObject]); } }); }, offClick:function (method, node) { if (node) { $(node).find('[data-click]').off('click'); }else { $('[data-click]').off('click'); } } }; return utils;});NOTE:无论是 define 还是 require,要想能够使用已知的模块,必须都要放在 其中的 模块名的数组([ ])中,无论是一级 require ,还是多级 require,他们都是在数组中;
2.4 require
require 用于调用 已定义的模块 完成页面渲染;与 define 的区别是,无返回值,不能够被外部其他的模块感知到;
示例代码:可以在用到某个 js 的时候再使用 require 加载;
/** * Created by xlch on 2017/2/6. *///加载配置文件js,以及默认提供的 modulerequire(['../main','module'],function (main,module) { require(["../help/util"],function (util) { util.quick.click({ delete:function () { alert("delete"); } }); require(['underscore'],function (_) { var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}]; console.log(_.pluck(stooges, 'name')); }); })})如果在加载配置文件的同时,还想使用 配置文件中配置的 module 的话,例如上面 main.js 中配置的 jquery:
可以这样:
require(['require', '../main', '../help/util'], function (require,main,util) { util.quick.click({ delete: function () { alert("delete 222"); } }); require(['backbone'], function (Backbone) { Backbone.Model.extend({}); }); require(['jquery'],function ($) { console.log($("#h2").text()); })})但是如果我仿照 define 中那样使用 jquery 的话,会报错 ,jquery 404 not found
他寻找的地址为 js/app/jquery,但是我 main 中配置的 baseUrl 为 js/lib ,这里使用的路径是 js/app ;
按照推断,应该是此时的 main.js 还没有加载,不知道推断的是否正确
//这里会报错,无法找到 js/app/jquery.js ,而 jquery 的真正路径配置在 main.js 中//说明,这里 main.js 应该还没有加载吗?按照上面的 baseUrl 产生规则//设置了 data-main,未设置 baseUrl,则 baseUrl 为 data-main 的路径//即 入口处贴的 js/app/home.js ,完全吻合;require(['require', '../main', '../help/util', 'jquery'], function (require,main,util) { var $ = require("jquery"); console.log($("#h2").text()); util.quick.click({ delete: function () { alert("delete 222"); } }); require(['backbone'], function (Backbone) { Backbone.Model.extend({}); }); require(['jquery'],function ($) { console.log($("#h2").text()); })})如果,这里我把 require 的 模块数组中的 jquery 去除,则可以成功跑通;如下代码调整require(['require', '../main', '../help/util'], function (require,main,util) { var $ = require("jquery"); console.log($("#h2").text()); util.quick.click({ delete: function () { alert("delete 222"); } }); require(['backbone'], function (Backbone) { Backbone.Model.extend({}); }); require(['jquery'],function ($) { console.log($("#h2").text()); })})另外,require 的模块数组 中提供了 domReady! ,作用是 保证 在 DOM 准备完毕之后 该 模块的函数 才能被调用;require(['domReady!'], function (doc) { //等待 DOM 加载完毕之后,调用该函数});为了防止加载时间过长,导致 requirejs 产生 超时的错误,可以在 配置文件 main.js 中 增加 waitSeconds 配置等待的最长时间,或者 使用 domReady() 方法调用;
require(['domReady'], function (dom) { domReady(function () { // DOM 加载完毕后执行 });});《 简单总结 ,未完待续 》
新闻热点
疑难解答