【问题标题】:$.mustache() is defined, but Mustache isn't defined when mustache() is invoked$.mustache() 已定义,但在调用 mustache() 时未定义 Mustache
【发布时间】:2014-08-21 06:54:02
【问题描述】:

我正在尝试将 Mustache 与 requireJS 和 jQuery 一起使用,由于 Chrome 的控制台输出正确,因此它似乎正在加载到浏览器中:

>$.mustache
<function (template, view, partials) {
    return Mustache.render(template, view, partials);
} 

但是当我尝试使用 mustache 函数时,它会给出错误 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);
});

【问题讨论】:

  • 好吧,如果你在控制台中测试,只要调用 js,它肯定会工作。如果它在代码中不起作用,可能是因为您在调用 js 之前尝试使用它
  • 查看此链接希望对您有所帮助stackoverflow.com/questions/6439935/…
  • 问题是它似乎甚至无法在控制台中运行。 $.mustache 本身被定义为一个函数,但是当我尝试使用它时,它说 Mustache 没有定义。而且在源代码中似乎也没有任何定义。也许我缺少额外的源代码?据我所知,我从官方网站获得的只是 jquery.mustache.js。

标签: javascript jquery requirejs mustache


【解决方案1】:

问题

Mustache 是 AMD 感知的,因此当您加载 mustache.js 文件时,它会检测到它正在使用 AMD 加载程序 (RequireJS) 运行,调用 define 并且不会将任何内容泄漏到全局空间中。耶!这是 AMD 感知模块的完美行为。如果没有 AMD-loader,它会做典型的事情:将单个符号导出到全局空间 (Mustache)。

然而,当你使用 Mustache 代码库中提供的 jQuery 插件时,你会得到一个 eldritch abomination,一个既能感知 AMD 又忽略 AMD 的生物,它不会泄露任何东西给全局空间,但依赖于将事物泄漏到全局空间。基本上,发生的情况是 Mustache 的核心,它是 AMD 感知的,被包装在添加 jQuery 支持的代码中,但是这个代码 not AMD 感知的。总而言之,此代码只有在在存在 AMD 加载器的环境中加载时才能正常工作。

你得到的错误是因为虽然 Mustache 没有向全局空间泄漏任何东西,但 jQuery 插件希望在全局空间中找到 Mustache

选项

您有多种选择:

  1. 不要使用与 Mustache 捆绑的 jQuery 插件。

  2. 使用丑陋的 RequireJS hack 使其工作。这包括故意将Mustache 泄漏到全局空间中。 (糟糕!)为mustache 模块声明一个shim,即使它调用define。 (当我尝试它时,它起作用了,但我不会打赌它会稳定,因为shim 是用于调用define 的代码。)

  3. 将包装器(哈哈!)包装到样板文件中,使其正常运行。

让包装器发挥作用

我更喜欢选项 3。这可以使用 Grunt 或 makerake、what-have-you 自动完成。配方是按此顺序连接 4 个文件:

  1. 在 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';
    
  2. 文件mustache/wrappers/jquery/mustache.js.pre。这与 Mustache 捆绑在一起。

  3. 文件mustache/wrappers/jquery/mustache.js.post。这与 Mustache 捆绑在一起。

  4. 在 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 中运行它没有任何问题。

【讨论】:

    【解决方案2】:

    当通过 CommonJS 接口调用 mustache 模块时(正如 require.js 所做的那样),mustache 模块不会导出全局 Mustache 对象 - 相反,当通过标签包含模块时,它会导出此对象。

    您可以在 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 对象将可用于 $.mustache 函数(即它会起作用) .

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-11
      • 1970-01-01
      • 2015-12-29
      • 1970-01-01
      • 2018-11-26
      • 2018-06-18
      • 2012-02-01
      • 2014-01-17
      相关资源
      最近更新 更多