模块不一样于传统意义上的脚本文件,由于它定义了一个良好做用域的对象,可以避免污 染全局的命名空间。它可以明确地列出其依赖,和全局对象无关地操做这些依赖,相反的, 接收这些依赖做为定义模块函数的参数。RequireJS 中的模块是模块模式的一个扩展,具备 不须要参考其余模块的全局设置的优点。
对于模块的 RequireJS 语法容许它们尽量快的被加载,甚至是无序的,可是可以以正 确的依赖顺序执行,因为没有建立全局变量,因此说在一个页面中加载多个版本的模块成为 了可能。
(若是你熟悉或正在使用 CommonJS 模块,那么你也能够参考下在 CommonJS 注解中的 关于如何将 RequireJS 模块映射到 CommonJS 模块中的相关资料)
磁盘上的每一个文件应当只有一个模块定义。各个模块能够经过优化工具划分为优化的包。 css
一、简单键值对
若是模块不依赖于任何模块,同时只是传递一些 name/value 对,那么只是传递了一个 原始的对象给 define():
//Inside file my/shirt.js:
define({ color: "black", size: "unisize" }); 算法
二、定义函数数组
若是模块不依赖于任何模块,可是须要使用函数作一些设置工做,那么定义它本身,传 递一个函数给 define():
//my/shirt.js now does setup work //before returning its module definition. define(function () { //Do setup work here
return { color: "black", size: "unisize" } });
浏览器
三、定义依赖的函数
app
若是模块有依赖,那么第一个参数应该是依赖名称的数组集合,第二个参数应该是一个 定义的函数。一旦全部依赖都已加载,那么将调用这个函数来定义模块。这个函数应该返回 一个定义模块的对象。这些依赖将做为参数传递给定义的参数,同时按照依赖顺序在参数中 列出来。
//my/shirt.js now has some dependencies, a cart and inventory //module in the same directory as shirt.js define(["./cart", "./inventory"], function(cart, inventory) { //return an object to define the "my/shirt" module. return { color: "blue", size: "large", addToCart: function() { inventory.decrement(this); cart.add(this); } } }
);
在上述案例中,my/shirt 模块已经建立。它依赖于 my/cart 和 my/inventory。磁盘上文 件结构是这样的:
my/cart.js my/inventory.js my/shirt.js
上述函数调用中指定了两个参数,’cart’ ’inventory’.这些表明了’./car’ ‘./inventory’模块。 上述函数直到 my/cart,my/inventory 模块加载完成后才被调用,它接收模块做为 cart 和 inventory 参数 定义全局的模块是明确不鼓励使用的,以便一个模块的多个版本可以在一个页面上同时 存在(参考高级用法)。同时函数的参数顺序应该和依赖的顺序相匹配。 函数调用的返回值定义了’my/shirt’模块。经过这种方式定义模块, ’my/shirt’并非做为 一个全局对象而存在的 异步
四、定义一个模块做为一个函数 ide
模块没有必要必定返回对象。函数中的任何合法返回值都是容许的。下面是一个返回一个函 数做为它的模块定义的模块示例:
//A module definition inside foo/title.js. It uses //my/cart and my/inventory modules from before, //but since foo/bar.js is in a different directory than //the "my" modules, it uses the "my" in the module dependency //name to find them. The "my" part of the name can be mapped //to any directory, but by default, it is assumed to be a //sibling to the "foo" directory. define(["my/cart", "my/inventory"], function(cart, inventory) { //return a function to define "foo/title". //It gets or sets the window title. return function(title) { return title ? (window.title = title) : inventory.storeName + ' ' + cart.name; } } );
函数
五、自定义模块工具
您可能会遇到的一些 define()函数调用,函数的第一个参数是模块名称:
//Explicitly defines the "foo/title" module: define("foo/title", ["my/cart", "my/inventory"], function(cart, inventory) { //Define foo/title object in here. } ); 这些一般是由优化工具生成的。你能够明确地命名模块名称,可是这样会致使模块的可 移植性不好。假如你把文件移到另一个目录,这时你须要修更名称。最好的实践是避免编 码模块名称,让优化工具自行优化模块名。优化工具须要添加模块名,以便在一个文件中可 以绑定多个模块,这样在浏览器中可以加载的更快。
优化
六、其余模块说明
一个文件一个模块: 按照模块到文件路径查找算法,每一个 JavaScript 文件应该只定义一个模块。优化工具会 将多个模块分组到优化的文件中,可是你只能经过优化工具将多个模块放到一个文件中。 Define()相对模块命名: 在 define()函数内部调用 require(‘./relative/name’)以前,确保’require’已经做为一个依赖, 只有这样相对名称才能被正确的解析: define(["require", "./relative/name"], function(require) { var mod = require("./relative/name"); }); 或更好的,对于解析 CommonJS 模块使用简洁的语法是可行的。 define(function(require) { var mod = require("./relative/name"); }); 这种形式,将使用 Function.prototype.toStrin()找到 require()调用,并把它们添加依赖 数组中,因为“require”已加载 ,所以这样的代码会正常解析相对路径。 相对路径真的很是有用,若是你在一个目录下建立了一些模块,那么你能够好其余人或 其余工程共享这些目录,同时你可以在那个目录下的兄弟模块获取到一个句柄,而不须要知 道目录的名称。 生成相对路径模块的 URL 你可能须要生成相对于模块的 URL。要作到这一点,将’require’做为依赖,使用 require.toUrl()生成 URL: define(["require"], function(require) { var cssUrl = require.toUrl("./style.css"); }); 控制台代码调试 若是你须要在 JavaScript 控制台和一个已经经过 require(["module/name"], function(){})加 载好的模块进行调试,那么你须要使用 require()函数经过模块名查询它 require("module/name").callSomeFunction() 注意:这个只有先经过 require 异步加载模块 require([‘module/name’])才有效。若是使用的 相对路径,好比‘./module/name’,这类的只有在 define 内部有效。