Cajon 是一个用于浏览器的 JavaScript 模块加载器,可以加载 CommonJS/node 和 AMD 模块。它构建在 RequireJS 之上。
您可以使用它以 CommonJS/node 风格为项目编写模块代码,然后使用 RequireJS 优化器将所有模块构建到符合 AMD 标准的包中。这使您可以使用小型 AMD API 填充程序(例如 almond)来获得经过良好优化的代码,而无需完整的运行时加载程序。
为什么使用这个而不是 RequireJS?一些可能的原因:
define ( function ( require ) {
/*module code here */
} ) ;
否则,您应该使用 RequireJS 或其他 AMD 加载器。
请注意下面的限制部分。如果你不听从它们,你可能会沮丧地咬牙切齿。
如果您不喜欢这个特定的加载器,但喜欢双 AMD 和 CommonJS/node 样式模块加载器的想法,那么您可能更喜欢 LinkedIn 的 Inject 加载器。
箱鼓由以下材料构成:
//@ sourceURL=
指定脚本调试器的脚本名称来评估它们。如果请求与 HTML 文档位于同一域,Cajon 将仅使用 XHR+eval 方法。如果脚本请求被认为是在另一个域上,它只会委托给默认的 requirejs.load() 函数,它将使用标签加载脚本,并期望它采用 AMD 格式,或者传统的“浏览器全局变量”脚本。
如果您知道您的用户将使用启用 CORS 的浏览器和服务器,您可以覆盖此行为以使用 XHR 处理某些跨域请求。请参阅下面的配置部分。
获取的脚本包装在以下 AMD 包装器中:
define ( function ( require , exports , module ) {
/* module code here */
} ) ;
它允许在包装的代码中使用 __dirname 和 __filename。
Cajon 将cajon
变量分配给与requirejs
变量相同的值,因此如果您想专门调用 cajon 的用法,可以使用它。然而,requirejs 优化器只理解require
、 requirejs
和define
,它不会理解cajon
。如果您使用优化器的mainConfigFile
选项,这一点尤其重要。
如果您希望代码可移植到 RequireJS、almond 和其他 AMD 加载器,最好只使用全局require
,并且仅在您想知道 cajon 是否可用时才检测cajon
。
有一个demo
目录显示示例使用,但基本上,将 cajon.js 放在标记中并通过
require([])
加载模块。但请注意下面的限制部分。
要优化演示,请运行:
node tools/r.js -o demo/app.build.js
这将在demo-built
目录中生成优化的项目。构建输出中的所有模块都将转换为 AMD 样式,以便可以跨域加载它们,而不需要特殊的 CORS 考虑。
app.build.js 构建配置文件要求 r.js 优化器为 2.0.2 或更高版本,因为它使用 2.0.2 的cjsTranslate
构建选项,将 CommonJS/node 模块转换为 Define() 包装的构建。
如果使用volo:
volo add cajon
如果使用 npm:
npm install cajon
或最新版本的 URL:
https://raw.github.com/requirejs/cajon/latest/cajon.js
因此,不要指望npm install
一些代码,然后就能够使用 cajon 来要求它。
Node 使用多个node_modules
路径查找来查找代码,这在浏览器上下文中效率不高。此外,许多 Node 模块依赖于 Node 的标准库或 Node 的环境,这些在 Web 浏览器中默认不可用。
如果你确实想使用一些 npm 安装的代码,并且你知道它将在浏览器中运行,你可以让它与 cajon 一起工作,但你可能需要使用paths 、 map和packages requirejs 配置来让它工作。
CommonJS/node 模块系统是同步的本地文件 IO 系统。所以他们允许这些类型的构造:
//first example
var id = someCondition ? 'a' : 'b' ;
var a = require ( id ) ;
//second example
var a ;
if ( someCondition ) {
a = require ( 'a' ) ;
} else {
b = require ( 'b' ) ;
}
第一个示例将在 AMD 浏览器环境中失败,因为在代码运行之前需要了解、下载和执行所有依赖项。如果“a”和“b”尚未处于该状态,则第一个示例可能会生成错误。
第二个示例可以工作,但要知道 AMD 加载程序将在运行该代码之前下载并执行“a”和“b”。
如果您使用运行时决策来获取依赖项,请使用 AMD 加载器支持的回调式 require():
var id = someCondition ? 'a' : 'b' ;
require ( [ id ] , function ( mod ) {
//do something with mod now
//that it has been asynchronously
//loaded and executed.
} )
或者考虑创建一个 AMD 加载器插件,它可以执行决策逻辑,但仍被视为单个字符串文字依赖项:
var dep = require ( 'has!condition?succesModuleId:failModuleId' ) ;
回调风格的 require 和 loader 插件都可以与 cajon 一起使用,因为它只是在幕后使用 requirejs。
如果请求与 HTML 文档位于同一域,Cajon 将仅使用 XHR+eval 方法。如果您知道将使用启用 CORS 的浏览器和服务器,则可以覆盖此行为。
在传递给加载器的cajon
配置中设置useXhr
函数:
require . config ( {
cajon : {
useXhr : function ( url , protocol , hostname , port ) {
//Return true if XHR is usable, false if the
//script tag approach to an AMD module/browser globals
//script should be used.
//url is the url being requested.
//protocol, hostname and port area all values from the
//current page that is using cajon. Compare them with
//what is in `url` to make your decision.
}
}
} ) ;
如果您需要在发送请求之前配置每个 XHR 对象,您可以实现一个onXhr
方法,该方法在 xhr.open() 之后、设置 xhr.onreadystatechange() 之前以及调用 xhr.send() 之前调用:
require . config ( {
cajon : {
onXhr : function ( xhr , url ) {
//xhr is the XHMLHttpRequest object.
//url is the URL the xhr object is set to use.
}
}
} ) ;
麻省理工学院
jQuery 基金会行为准则。