Requirejs高级应用(五):模块的唯一性鉴别

单独写一篇文章来阐述这类问题,是因为这个问题太容易犯错,并且太重要了。

对require加载的模块来说,它们都是单例的,但这个唯一标识取决于它们的模块名称及相对路径,与它们的绝对路径无关,换句话说,每个文件(模块)唯一性的辨别完全依赖与模块名称。

再强调一次,模块的唯一性与它们的访问路径无关,即使是地址完全相同的一份JS文件,如果引用的方式与模块的配置方式不一致,依旧会产生多个模块。

看下面的例子,假定目录结构如下:

require.js
* em/
    * User.js
index.html

require的配置信息如下:

require.config({
    baseUrl: './',
    paths : {
        'user' : './em'
    }
})

User.js的文件内容如下:

define([], function() {
    return {
        username : 'yiifaa',
        age       : 20
    };
});

下面看引用方式:

require(['user/User'], function(user) {
    //  修改了User模块的内容
    user.username = 'yiifee';
    //  em/User以baseUrl定义的模块进行访问
    //  'user/User'以path定义的模块进行访问
    require(['em/User', 'user/User'], function(u1, u2) {
        //  输出的结果完全不相同,u1为yiifaa,u2为修改后的内容yiifee
        console.log(u1, u2);
    })
})

从上面的实验结果可以看出,即使是完全相同的一份文件,由于模块请求的方式差异,导致它们创建了两份实例,完全没有违反了AMD的设计原则。

项目问题1:requirejs的全局变量无效

在require的实际应用中,我们经常会创建一份文件用于全局变量,如果出现了全局变量初始化后依旧无效的问题,请仔细检查他们的请求方式是否完全依赖于同样的模块名(尤其是运用相对路径时)。

很神奇的地方在于,虽然模块不一致,但无论请求多少次require函数,网络请求依旧只会发送一份,即使添加了urlArgs参数,如下:

require.config({
    //  其他配置信息
    ……
    //  每次发送JS请求时,会自动添加参数后缀
    urlArgs: "bust=" +  (new Date()).getTime()
});

结论:AMD到底怎样引用模块

据我个人经验,要想保障AMD项目清晰明了,调用简单,最好基于以下原则:
1. 项目中的自编码模块最好基于根路径引用,这样在根路径下就会产生很多根模块,跨模块调用时最好基于根模块进行调用,
2. 如有困难或者需要改造,请优先定义packages,而不要使用paths定义自编码模块;
3. 如果非要使用paths,那就减弱或者消除packages对项目代码的使用;
4. 如果还不行,那就取消requie全局变量,改用window全局变量,但这样性能会有损耗。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值