requireJS学习笔记

Posted 做枚温婉的妹纸吧哈哈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

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

以上是关于requireJS学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

requireJS学习笔记

Python学习笔记-APP图标显示未读消息数目

go语言学习笔记 — 基础 — go工具(5.2): 基准测试 (性能测试)—— 获得代码内存占用和运行效率的性能数据

requireJs笔记

模块化开发RequireJS之shim配置

requirejs2读书笔记