我正在尝试使用Mustache以及requireJS和jQuery,并且它似乎被加载到浏览器中,因为Chrome的控制台输出正确:
>$.mustache
<function (template, view, partials) {
return Mustache.render(template, view, partials);
}
但是当我尝试使用胡子函数时,它会给出错误ReferenceError: Mustache is not defined
并指向mustache.js文件本身的第588行:
$.mustache = function (template, view, partials) {
return Mustache.render(template, view, partials);
};
以下是我在main.js文件中调用它的方法:
require(['mustache'], function(Mustache){
var view = {test:'TEST'};
var temp = '{{test}}!!!';
$.mustache(temp,view);
});
答案 0 :(得分:3)
Mustache具有AMD感知能力,因此当您只加载mustache.js
文件时,它会检测到它正在运行AMD-loader(RequireJS),调用define
并且不会泄漏任何内容到全局空间。好极了!对于支持AMD的模块,这是完美的行为。如果没有AMD-loader,它就是典型的事情:将单个符号导出到全局空间(Mustache
)。
然而,当你使用Mustache代码库提供的jQuery插件时,你会得到一个 eldritch憎恶,一个既有AMD感知却又忽略了AMD的生物,它不泄漏任何东西全球空间,但依赖于泄漏到全球空间。基本上,发生的事情是Mustache的核心,它是AMD感知的,包含在添加jQuery支持的代码中,但是这些代码不 AMD-aware。总而言之,只有在存在AMD加载程序的环境中不加载时,此代码才能正常运行。
你得到的错误是因为虽然Mustache没有泄漏到全局空间,但jQuery插件希望在全局空间中找到Mustache
。
您可以选择多种方式:
请勿使用与Mustache捆绑在一起的jQuery插件。
使用丑陋的RequireJS黑客来使其工作。这包括故意将Mustache
泄漏到全球空间。 (哎呀!)为shim
模块声明mustache
,即使它调用define
。 (当我尝试它时,它可以工作,但我不会打赌它完全稳定,因为shim
用于不调用define
的代码。)
将包装纸(ha!)包装到样板中的样板中。
我更喜欢选项3.这可以使用Grunt或make
,rake
自动完成。配方是按顺序连接4个文件:
在Mustache的jQuery包装器之前放置的代码:
(function (factory) {
// If in an AMD environment, define() our module, else use the
// jQuery global.
'use strict';
if (typeof define === 'function' && define.amd)
define(['jquery', 'mustache'], factory);
else
factory(jQuery, Mustache);
}(function (jQuery, Mustache) {
'use strict';
文件mustache/wrappers/jquery/mustache.js.pre
。这与Mustache捆绑在一起。
文件mustache/wrappers/jquery/mustache.js.post
。这与Mustache捆绑在一起。
在Mustache的jQuery包装器之后放置的代码:
}));
将这4个文件按此顺序组合在一起后,您将获得一个可以使用RequireJS加载的文件。
这是一个例子。在以下示例中,所有第三方组件都随Bower一起安装。 js
子目录包含如上所述连接四个文件的结果,此结果名为jquery.mustache.js
。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8"/>
<script type="text/javascript" src="bower_components/requirejs/require.js"></script>
<script id="template" type="text/html">
<p>Hi, {{name}}</p>
</script>
</head>
<body>
<script>
require.config({
baseUrl: ".",
paths: {
jquery: "bower_components/jquery/dist/jquery",
mustache: "bower_components/mustache/mustache",
"jquery.mustache": "js/jquery.mustache"
}
});
require(["jquery", "jquery.mustache"], function ($) {
console.log($.mustache);
$(document.body).append($("#template").mustache({name: "blah"}));
});
</script>
</body>
</html>
我在Chrome中运行它没有任何问题。
答案 1 :(得分:1)
当通过CommonJS接口调用时,胡须模块不会导出全局Mustache对象(如require.js那样) - 当通过标记包含模块时,它会导出此对象。
你可以在jquery.mustache.js源代码的第23行看到这个: jquery.mustache.js (gist)
jQuery插件引用此全局Mustache对象,当require.js导入jquery.mustache.js时,该对象不存在。
您需要告诉require.js导出Mustache对象 - 这是通过require.config设置完成的,使用 shim 属性:
require.config({
shim: {
'mustache': {
exports: 'Mustache'
}
}
});
在调用 require()之前包含此代码,并且(全局)Mustache对象可用于 $ .hustache 函数(即它将起作用)