Cajon:一款高效的JavaScript模块加载器
Cajon是一个专为浏览器设计的JavaScript模块加载器,它能够加载符合CommonJS/node和AMD规范的模块,并基于业界知名的RequireJS构建。通过使用Cajon,你可以以CommonJS/node风格编写你的项目模块,然后利用RequireJS优化器将所有模块打包成一个AMD兼容的捆绑包。这意味着你可以使用像almond这样的小型AMD API适配器,从而获得简洁且高度优化的代码,无需完整的运行时加载器。
为何选择Cajon?
如果你有以下需求,Cajon可能正是你需要的:
- 不喜欢在模块代码周围使用类似
define(function(require) {...})
的包装。 - 拥有一套已经按CommonJS/node风格编写的代码库,希望进行重用。
如果你对这个特定的加载器不感冒,但又想要一个能同时支持AMD和CommonJS/node风格模块加载的工具,那么LinkedIn的Inject加载器可能会是另一种不错的选择。
工作原理
Cajon基于RequireJS(版本需为2.0.2或更高),并重写了requirejs.load
方法,采用异步XMLHttpRequest请求来获取脚本,随后通过eval
执行,并使用//@ sourceURL=
注解来帮助脚本调试器识别源文件位置。
Cajon仅当请求的脚本与HTML文档处于同一域时才会使用XHR+eval方式加载。如果脚本请求被认为是在另一个域中,则会委托给默认的requirejs.load()
函数,它将以AMD格式加载脚本,或者处理传统的“浏览器全局变量”脚本。
若要跨域请求时也使用XHR,你可以自定义配置,详情请参阅下方的配置部分。
加载的脚本会被包裹在下面这种AMD包装器内:
define(function (require, exports, module) {
/* module code here */
});
并且,它允许你在包裹代码内使用__dirname
和__filename
。
Cajon将cajon
变量设置为与requirejs
相同,因此你可以使用cajon
,但如果想要保持代码对RequireJS、almond和其他AMD加载器的兼容性,最好还是直接使用全局require
。只有当你需要确认cajon
是否可用时,才进行检测。
如何使用
示例目录中的demo
展示了基本的使用方法,基本上只需在HTML中引用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
-
或者直接从最新发布下载:
https://raw.github.com/requirejs/cajon/latest/cajon.js
限制条件
-
不使用Node的模块ID到路径规则 这意味着你不能期望通过
npm install
安装一些代码后,就直接通过cajon引用它们。因为Node使用多个node_modules
路径查找规则,而在浏览器环境中执行效率较低。另外,许多Node模块依赖于Node的标准库或Node环境,这些在Web浏览器中默认不可用。 -
避免动态计算的
require('')
调用 CommonJS/node模块系统是同步的本地文件IO系统,允许如下的代码结构:var id = someCondition ? 'a' : 'b'; var a = require(id);
在AMD浏览器环境下,此类代码可能会出错,因为所有依赖项在代码运行前都需要被预先知道、下载并执行。
配置
Cajon仅当请求的资源与HTML文档在同一域时使用XHR+eval方式。你可以覆盖这一行为,假设你的用户都在使用支持CORS的现代浏览器和服务器,可以通过配置useXhr
函数:
require.config({
cajon: {
useXhr: function (url, protocol, hostname, port) {
// 返回true表示可以使用XHR,false则使用
// 脚本标签方式加载AMD模块或传统浏览器全局脚本。
// url是即将请求的URL,
// protocol、hostname和port是当前页面的值,与URL对比后作出决定。
}
}
});
如果你需要在xhr发送请求之前对其进行配置,还可以实现onXhr
方法:
require.config({
cajon: {
onXhr: function (xhr, url) {
// xhr是XMLHttpRequest对象。
// url是xhr准备使用的URL。
}
}
});
许可协议
Cajon遵循MIT许可。
行为准则
Cajon提供了一种高效且灵活的方式来管理和组织你的JavaScript代码库,让你可以充分利用CommonJS的便利性,同时也适应AMD的模块化标准。无论是用于大型项目还是小型应用,它的强大功能和易用性都将为你带来极大的益处。现在就开始尝试,让Cajon成为你开发工具箱的一部分吧!