【requirejs】基础总结

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 中,所以还需要下面的 require
define(['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 中,所以还需要下面的 require
define(['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,以及默认提供的 module
require(['../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 加载完毕后执行
  });
});


《  简单总结 ,未完待续 》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值