Почему у моих ручек нет метода компиляции?

Я создаю проект Backbone с Handlebars, и у меня возникает проблема с Handlebars, не находя метод компиляции. Вот мой файл конфигурации:

require.config({
  hbs: {
    templateExtension: '.hbs'
  },
  paths: {
    backbone: "libs/backbone/backbone",
    handlebars: 'libs/handlebars/handlebars.amd',
    hbs: 'libs/requirejs-hbs/hbs',
    jquery: 'libs/jquery/jquery',
    jqueryMockAjax: 'libs/jquery-mockjax/jquery.mockjax',
    text: 'libs/requirejs-text/text',
    templates: 'templates/',
    underscore: 'libs/underscore/underscore'
  },
  shim: {
    backbone: {
      deps: [
        'underscore',
        'jquery'
      ],
      exports: 'Backbone'
    },
    hbs: {
      deps: ['handlebars'],
      exports: 'hbs'
    },
    jqueryMockAjax: {
      deps: [ 'jquery' ],
      exports: '$.mockjax'
    },
    underscore: {
      exports: '_'
    }
  }
});

require(['app'], function(App) {
  'use strict';

  var app = new App();
  app.render();
});

Вот app.js, который я пытаюсь сделать:

define(function(require) {

  var Backbone = require('backbone');
  var testTemplate = require('hbs!templates/test');

  var router = Backbone.View.extend({
    el: $('body'),
    template: testTemplate,
    render: function() {
      return $(this.el).html(this.template());
    }
  });

  return router;
});

Когда Handlebars вызывает файл hbs.js в строке 25, он не может найти функцию compile

define(["handlebars"], function(Handlebars) {
  var buildMap = {},
      templateExtension = ".hbs";

  return {

    // http://requirejs.org/docs/plugins.html#apiload
    load: function (name, parentRequire, onload, config) {

      // Get the template extension.
      var ext = (config.hbs && config.hbs.templateExtension ? config.hbs.templateExtension : templateExtension);

      if (config.isBuild) {
        // Use node.js file system module to load the template.
        // Sorry, no Rhino support.
        var fs = nodeRequire("fs");
        var fsPath = config.dirBaseUrl + "/" + name + ext;
        buildMap[name] = fs.readFileSync(fsPath).toString();
        onload();
      } else {
        // In browsers use the text-plugin to the load template. This way we
        // don't have to deal with ajax stuff
        parentRequire(["text!" + name + ext], function(raw) {
          // Just return the compiled template
 ****HERE onload(Handlebars.compile(raw));
        });
      }

    },

    // http://requirejs.org/docs/plugins.html#apiwrite
    write: function (pluginName, name, write) {
      var compiled = Handlebars.precompile(buildMap[name]);
      // Write out precompiled version of the template function as AMD
      // definition.
      write(
        "define('hbs!" + name + "', ['handlebars'], function(Handlebars){ \n" +
          "return Handlebars.template(" + compiled.toString() + ");\n" +
        "});\n"
      );
    }

  };
});

Переменная Handlebars дает мне среду Handlebars, но в ней есть дополнительный слой, поэтому мне нужно изменить эту строку на Handlebars.default.compile(raw). Откуда возникает этот объект default и как я могу избавиться от него? Я бы не стал беспокоиться об этом, но если я сдержу этот проект где-то еще, мне всегда придется помнить об этом.

Ответы

Ответ 1

Вот как я исправил эту проблему, хотя я не совсем понимаю, почему конфигурация выше не работает. В плагине hbs была папка со всеми необходимыми ей зависимостями, например handlebars. Когда я ссылался на копию handlebars, содержащуюся в каталоге hbs, тогда все работало так, как предполагалось. Я не понимаю, почему ванильная копия handlebars не работала. Я не использовал время выполнения handlebars, это была полная версия, но все еще была проблема. После того, как я решил это, мои шаблоны просто работали.

Ответ 2

Я просто столкнулся с этим сам, используя Handlebars для этого первого раза. Вероятно, вы используете сборку Handlebars "runtime". Я включил это в свои требования, ошибочно полагая, что это была мини-версия или что-то в этом роде.

Но на самом деле версия исполнения значительно меньше, поскольку она исключает компилятор шаблона и используется только для предварительно скомпилированных шаблонов. Если вы компилируете клиентскую копию шаблона, вам нужна полная версия из http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v3.0.3.js (Примечание: эта ссылка может быть устаревшей; вам, вероятно, лучше перейти непосредственно на handlebarsjs.com и искать текущую загрузку для "полной версии", в отличие от времени выполнения.)

В противном случае вы можете выполнить инструкции на веб-сайте Handlebars для запуска компилятора шаблона. Для этого вам понадобится node. Компилятор шаблона создает файл JavaScript, содержащий предварительно скомпилированный код шаблона, который вам нужно связать с вашей страницей вместе со сборкой времени выполнения Handlebars.