问题描述
我正在尝试使用Mustache以及requireJS和jQuery,并且它似乎被加载到浏览器中,因为Chrome的控制台正确输出:
I am trying to use Mustache along with requireJS and jQuery, and it seems that it is being loaded into the browser since Chrome's console outputs correctly:
>$.mustache
<function (template, view, partials) {
return Mustache.render(template, view, partials);
}
但是当我尝试使用胡子函数时,它会给出错误 ReferenceError:未定义Mustache
并指向mustache.js文件中的第588行:
But when I try to use the mustache function it gives the error ReferenceError: Mustache is not defined
and points to line 588 in the mustache.js file itself:
$.mustache = function (template, view, partials) {
return Mustache.render(template, view, partials);
};
以下是我在main.js文件中调用它的方法:
Here is how I'm invoking it in the main.js file:
require(['mustache'], function(Mustache){
var view = {test:'TEST'};
var temp = '{{test}}!!!';
$.mustache(temp,view);
});
推荐答案
问题
Mustache具有AMD感知能力,因此当您只加载 mustache.js
文件时,它会检测到它正在运行AMD-loader(RequireJS),调用 define
并且不会将任何内容泄漏到全局空间中。好极了!对于支持AMD的模块,这是完美的行为。如果没有AMD-loader,它会做一些典型的事情:将一个符号导出到全局空间( Mustache
)。
The Problem
Mustache is AMD-aware so when you just load the mustache.js
file, it detects that it is running with an AMD-loader (RequireJS), calls define
and does not leak anything into the global space. Yay! This is perfect behavior for an AMD-aware module. And if there is no AMD-loader, it does the typical thing: export a single symbol into the global space (Mustache
).
然而,当你使用Mustache代码库提供的jQuery插件时,你会得到一个 eldritch憎恶,一个既有AMD感知却又忽略了AMD的生物,它不泄漏任何与全球空间相关的东西,但依赖于泄漏到全球空间的东西。基本上,发生的事情是Mustache的核心,它是AMD感知的,包含在添加jQuery支持的代码中,但是这些代码不 AMD-aware。总而言之,只有在存在AMD加载程序的环境中加载 时,此代码才能正常运行。
However, when you use the jQuery plugin that is available with the Mustache codebase you get an eldritch abomination, a creature which is both AMD-aware and yet ignores AMD, which does not leak anything to the global space and yet depends on leaking things to the global space. Basically, what happens is that Mustache's core, which is AMD-aware is wrapped in code that adds the jQuery support but this code is not AMD-aware. Altogether, this code will work well only if it is not loaded in an environment where there is an AMD-loader present.
错误你get是因为虽然Mustache没有泄漏到全局空间,但jQuery插件期望在全局空间中找到 Mustache
。
The error you get is because while Mustache does not leak anything to the global space, the jQuery plugin expects to find Mustache
in the global space.
您可以选择多种方式:
-
不要使用与Mustache捆绑在一起的jQuery插件。
Don't use the jQuery plugin bundled with Mustache.
使用丑陋的RequireJS黑客攻击让它起作用。这包括故意将 Mustache
泄漏到全球空间。 (哎呀!)为小胡子
模块声明 shim
,即使它调用 define
。 (当我尝试它时,它可以工作,但我不会打赌它完全稳定,因为 shim
用于不调用的代码 define
。)
Use ugly RequireJS hacks to make it work. This includes deliberately leaking Mustache
into the global space. (Yuck!) Declaring a shim
for the mustache
module even though it calls define
. (When I tried it, it worked but I would not bet on this being stable at all, because shim
is for code that does not call define
.)
将包装器(ha!)包装到样板中的样板中。
Wrap the wrapper (ha!) into boilerplate that makes it behave.
让包装器行动
我更喜欢选项3。可以使用Grunt或 make
, rake
进行自动化,你有什么用。配方是按以下顺序连接4个文件:
Getting the Wrapper to Behave
I prefer option 3. This can be automated using Grunt or make
, rake
, what-have-you. The recipe is to concatenate 4 files in this order:
-
在Mustache的jQuery包装器之前放置的代码:
Code to put before Mustache's jQuery wrapper:
(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捆绑在一起。
The file mustache/wrappers/jquery/mustache.js.pre
. This is bundled with Mustache.
文件 mustache / wrappers / jquery / mustache.js.post
。这是与Mustache捆绑在一起的。
The file mustache/wrappers/jquery/mustache.js.post
. This is bundled with Mustache.
在Mustache的jQuery包装器之后放置的代码:
Code to put after Mustache's jQuery wrapper:
}));
将这4个文件合并在一起顺序,你得到一个可以用RequireJS加载的文件。
Once these 4 files are combined together in this order, you get a file that you can load with RequireJS.
这是一个例子。在以下示例中,所有第三方组件都随Bower一起安装。 js
子目录包含如上所述连接四个文件的结果,此结果名为 jquery.mustache.js
。
Here's an example. In the following example, all third party components were installed with Bower. The js
subdirectory contains the result of concatenating the four files as explained above and this result is named 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中运行此功能没有任何问题。
I've run this in Chrome without any problems.
这篇关于$ .mustache()已定义,但调用mustache()时未定义Mustache的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!