文件目录如下:
root-|index.html
|require.js
|main.js
|jquery.min.js
|math.js
index.html:
<head>
<script type="text/javascript" src="require.js" data-main="main" defer async="true"></script>
</head>
main.js:
require.config({
paths: {
"jquery": "jquery.min",
"math": "math"
}
});
require(['jquery','math'], function ($,math){
console.log('main');
});
math.js:
define(['jquery'],function($){
console.log('math');
var add = function(a,b){
return a+b;
};
return{
add: add
};
});
在浏览器的Network可以看到加载js的情况:
疑问:
main.js模块依赖了jquery模块和math模块,由于异步我视为开了两个线程;第二个math线程又依赖了jquery模块,为何没有再一次请求该资源?requireJS内部机制是怎样的?
如果你有时间去看看 sea 或者 requirejs 的源码就能明白,其实原理并不复杂。
如果没有显式的指定名称,你的源文件路径(含目录和文件名)就是模块的名称。当然它内部会进行一些处理,使名称能唯一对应一个模块的定义。
那么模块的定义是一个
function
,这个function
实际是一个 factory(工厂模式,不明白的话就去搜下),这个 factory 在需要使用的时候(require("xxxx") 的时候)才有可能会被调用。为什么是有可能?因为如果检查到已经调用过,已经生成了模块实例,就直接返回模块实例,而不再次调用工厂方法了。这个过程大概是这样的(非常简化的,只是个示意,加载和依赖都忽略了,想了解详情自己去看源码)
对于加载的外部模块也说,也是一样的。尤其是像 jQuery 这些,在写源码的时候已经考虑了兼容 AMD 的问题,所以可以很好的用于 requirejs 依赖加载。