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.exports
或exports
对象来导出模块内的方法、属性,方便外部模块引用。
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
是有baseUrl
和paths
来设置的。
由于浏览器是不识别require
、define
等的。因此需要在页面加载文件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的时候会把依赖以及依赖的依赖。。。中的也排除掉,即便自身显示地依赖了‘依赖的依赖’中某个模块。
对include
和exclude
的解释,官方的说明比较清晰:
参考:r.js/build/example.build.js
问题:当将公用模块打包到一个文件后,别的文件要加载其中的某个模块的时候是怎么加载进来的?
以上是关于requireJS学习笔记的主要内容,如果未能解决你的问题,请参考以下文章