除开官方文档外 这篇博客挺好的 https://www.ibm.com/developerworks/cn/web/1209_shiwei_requirejs/
一般看完会有个疑问 define和require 区别是什么
define总共有三步 参考http://www.adobe.com/devnet/html5/articles/javascript-architecture-requirejs-dependency-management.html
Loads the specified dependencies
Calls the callback function
Registers the return value from the callback function as the module
require就是前2个,也就是说require不注册新模块,只是用别的模块。
使用上来说 define定义了一个模块 只要在被其他东东引用它的时候才会被执行 require就不一样 类似于函数的调用
来一个最基本的
<!DOCTYPE html> <html> <head> <title>My Sample Project</title> <!-- data-main 属性告诉 require.js 在 require.js 加载之后异步加载 js/main2.js --> <!--这个main2.js是主要文件 它依赖于各种其他模块 --> <!--PS 这里隐式说明了baseUrl是js这个文件夹 PS 最新版requirejs已经不再支持data-main这样的方式 且入口文件要用require的方式--> <script data-main="js/main2" src="js/require.js"></script> <script type="text/javascript" src='js/ano.js'></script> </head> <body> <h1>My Sample Project</h1> </body> </html>
PS:data-main中的文件时异步加载的 所以开始解析ano.js的时候 main2不一定加载完成了
这是main2
console.log('main2'); //require([moduleID,...],function(...){}); //指定模块的时候 无需指定.js后缀 因为默认是加载js文件 //并且这里在加载模块的时候 默认根据baseUrl + paths的方式 //baseUrl已经在index.html中指定 //一般情况下 moduleID就是文件名 //如果是以 .js结尾 / "http"开头 将会以index.html文件为baseUrl //依赖一个原始的库 //比如jQuery require(["jQuery2.1.1"],function($){ console.log($);//undefined //这是为什么呢? 因为jquery模块名字必须是jquery 这里模块名字是jQuery2.1.1 //所以似乎只有把文件名改为 jquery 才能用 (因为依赖的这里就是填写路径) }); require(["jquery"],function($){ console.log($); //ok }); //但是这样的规定太限制不是嘛 //当然最常见的办法是使用config来配置路径 但是模块名还是jquery //所以我们需要一个配置 这样jQuery的库的文件名就比较随意了 require.config({ paths: { 'jquery': './jQuery2.1.1' } }); require(["jquery"],function($){ console.log($); }); //我就是想改模块名怎么办呢? //参考http://www.zfanw.com/blog/require-js.html require.config({ paths: { 'jquery2': './jQuery2.1.1' }, shim: { 'jquery2': { exports: '$' } } }); //在config中为jQuery库设置了模块名 require(["jquery2"],function($){ console.log('after shim jQuery2.1.1============='); console.log($); }); //依赖一个define的模块 //[]中是模块的文件路径 不可以写后缀 写了后缀的话 表示是相对于html文件所在路径 //PS ./表示当前目录 可以省去 所以没必要写为./lib/zepto //zepto.js中定义的模块名也应该是lib/zepto //所以建议最好不写模块名 让requireJS来帮我们做 //否则虽然zepto虽然被加载 但是回调函数参数得不到值 //PS 这个函数在所依赖的模块加载完成之前不会执行 require(['lib/zepto'], function ($) { console.log('zepto============================='); console.log($); }); //PS define会在require之前执行 //PS 一个JS中只能有一个define // define(["lib/zepto"],function($){ // console.log('zepto===def=========='); // console.log($); // }); //带有模块名字的define //如果该文件是index中data-main中引用的文件 而且还想使用define来定义一个非匿名模块的话 //模块的名字要和文件名相同 //否则不执行模块 define('main2',["jquery"],function($){ console.log('my jquery==========='); console.log($); }); //PS Require JS 会自动根据文件名(不含后缀名,即不含 ".js")来给定义的模块命名 //你肯定会想 这样的话 define 和 require有什么区别 //define总共有三步 参考http://www.adobe.com/devnet/html5/articles/javascript-architecture-requirejs-dependency-management.html // Loads the specified dependencies // Calls the callback function // Registers the return value from the callback function as the module //require就是前2个
再看看一个完整的例子
require.config({ baseUrl: "./js", paths: { "common": "../common", "jquery":"../commonLib/jquery2.1.1" //实际路径是 bathUrl + paths 配置的路径 } }); //define中碰到了jquery 实际上依赖的就是 上面配置的路径 即js/../commonLib/jquery2.1.1 //PS jquery这个模块的名字必须是 jquery(全小写) define(['jquery',"helper/util", 'common/common1/common11'],function( $,util, common11){ console.log('main1'); console.log($); util.getName(); common11.getName(); });
['xx'] 方括号中的内容实际上就是文件路径 只不过对于jQuery 这个值必须是jquery 也就算是说jquery文件路径必须是
baseUrl/jquery 也就是js/jquery.js 不过一般jquery都不会直接在js下
本例子中jquery在和js同级目录下的commonLib中 因为我前面有个config 所以会依照config中的路径去寻找
模块应该在怎么写呢?
define(['lib/jquery','lib/zepto'],function($,$$){ console.log($); //undefined jquery默认模块名字只能是jquery 所以必须通过path 将模块名jquery映射为jquery文件实际路径 console.log($$); console.log('helper util'); return { getName:function(){ console.log('helper util'); } } });
这个模块将被上面的文件引用 上面定义了baseUrl是js 因此该模块依赖的文件实际路径是 js/lib/zepto
很惊讶!竟然不写模块名,因为可以省略。因为模块名也要和路径一致,所以可以省略。
要加的话 也一定是 helper/util