requireJS学习笔记

AMD、CMD与commonJS

requireJS实现了AMD规范,即异步加载模块,模块加载的时候不会阻塞后续代码的执行,将模块加载完后的操作(依赖该模块的程序)放到回调函数中进行。这种规范适合于浏览器端。例如:

require(['module1', 'module2'], function(mod1, mod2) {
    //do something; //当module1/2加载完后会执行该回调。加载时不阻塞require后面的代码
});

而(node服务端采用的是commonJS规范,commonJS是同步的,因为文件就存在于服务器,require进来的时候比较快)。例如:

var module = require ('module');
module.func();

一个文件就是一个模块,通过module.exportsexports 对象来导出模块内的方法、属性,方便外部模块引用。

requireJS不光实现了异步加载,避免页面假死,同时还管理了模块间的依赖,使得代码更容易维护。

而AMD也是异步加载的规范,与AMD不同的是,AMD推崇依赖前置,即提前加载好依赖的模块,而CMD推崇依赖就近加载(延后执行依赖模块,as lazy as possible),要用的时候才加载。二者的主要区别就是所依赖的模块的执行时机不同(依赖的加载怎么异步的?)。
例如:

  • AMD:
define(['a', 'b'], function(a, b) { //当依赖的模块加载完成执行定义函数
    a.func();  //a、b模块提前加载好
    b.func();
    return { 
        ...
    };
});

如果有代码加载上面定义的模块,则会先加载[] 中所依赖的模块。
- CMD:

define(function(require, exports, module) {
    var a = require('a');
    a.func();
    ...
    var b = require('b');
    b.func();
});

为了加载commonJS规范的模块,应该使用和CMD类似的加载依赖方式(无法通过数组参数加载依赖):

 define(function(require, exports, module) {
        var a = require('a'),
            b = require('b');

        //Return the module value
        return function () {};
    }
);

此外,如果依赖是相对路径,要讲require 作为依赖添加到依赖参数:

define(["require", "./relative/name"], function(require) {
    var mod = require("./relative/name");
});

因此,最好的方式就是直接使用上面的commonJS的方式(simplified CommonJS wrapping,requirejs对这种包装会解析成AMD的模式)。

requireJS的使用

requireJS使用ModuleId来替代文件路径。moduleId 是有baseUrlpaths 来设置的。
由于浏览器是不识别requiredefine 等的。因此需要在页面加载文件require.js 。此外,还可以对模块的基准路径、路径、不遵循AMD规范的模块进行配置。
有两种方式,一种是调用require.config() 方法:

require.config({
    baseUrl: 'js',
    paths: {
        'module1': 'lib/module1',
        ...
    },
    shim: {
        'lib/jquery.validate': ['jquery'],
        ...
    }
});

显然需要在require.js 文件引入之后才能调用该方法。
一种是定义一个require 全局对象:

var require = {
    //内容同上
};

该对象需要在require.js 文件引入之前进行定义。

requireJS实现机制

RequireJS使用head.appendChild()将每一个依赖加载为一个script标签。
RequireJS等待所有的依赖加载完毕,计算出模块定义函数正确调用顺序,然后依次调用它们。

问题: 动态生成的script标签?控制加载顺序就是生成标签的顺序,利用script标签加载好后出发load事件?

项目中提前定义require 为收集函数来收集页面中出现的require 方法,并放到页面结尾处再执行。不过使用配置文件中再次声明一个require对象覆盖了前面定义的收集函数。

参考:
requireJS中文文档

requireJS中的r.js

由于一个模块是一个JS文件(生成script 标签插入到head),加载多个模块的时候会增加请求数目。requireJS提供了一个工具即r.js来进行JS文件的合并。
定义一个模块的时候指定依赖可以使用这种方式:

//test.js

define(['jquery', 'common'], function($, common) {
    // do something

    return {
    };
});

或者采用兼容commonJS语法的方式:

define(function(require,[exports, module]) {
    var $ = require('jquery');
    var common = require('common');
    // do something

    return {
    };
});

还有当以字符串数组例如require(['']) 的形式加载模块时。以上方式在r.js在进行合并时,默认会将定义的模块及其依赖的诸如jquery、common等模块合并到一个JS文件中,除非你在build.js配置文件中指定要exclude哪些文件,这样就不会合并指定的文件了。另外也可以使用include来动态指定要包括哪些文件,这样可以添加在静态分析的时候没有合并的文件。合并的时候会把直接依赖、以及依赖的依赖…均合并到一个文件中。

在html中的引入:

require(['common'], function() {
    require(['test'], function(module) {
        //do something
    });
});

并不是说test依赖于common,而是指定加载顺序,必须是common加载完后才能加载test。该处与模块的合并打包没有关系,仅仅指定加载顺序。模块的合并打包只与在定义模块的时候有无依赖以及build.js中的include和exclude有关。
common中包含了一些公用的文件,可以缓存。

如果A依赖B,B依赖C,在没有做exclude的时候A中会包含B、C以及A自身的模块内容。

如果A依赖B、C,B依赖C,A把B exclude了,那么也会默认把C也exclude掉。即exclude的时候会把依赖以及依赖的依赖。。。中的也排除掉,即便自身显示地依赖了‘依赖的依赖’中某个模块。

includeexclude 的解释,官方的说明比较清晰:
这里写图片描述

参考:r.js/build/example.build.js

问题:当将公用模块打包到一个文件后,别的文件要加载其中的某个模块的时候是怎么加载进来的?

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值