Модули кендо и RequireJS (r.js) не играют хорошо. (Ошибка при загрузке)

Я использую Kendo UI версия 2013.1.514 а также RequireJS (r.js версия 2.1.6)

Мой проект отлично работает по стандарту RequireJS загрузка по требованию.

Однако, когда я пытаюсь использовать оптимизатор, ни один из кендо не будет загружен. В том числе любой из них дает знаменитый и раздражающий Uncaught Error: Mismatched anonymous define() module: ошибка.

Это моя конфигурация:

{
    "baseUrl": "../Scripts",
    "name": "../Scripts/js_modules/base_module.js",
    "include": [],
    paths: {
        k: "Frameworks/kendo-2013.1.514-fixed",
        jquery: "Frameworks/jQuery/jquery.min",
        jplugin: "Frameworks/jQuery",
        f: "Frameworks/"
    },
    shim: {
        'jquery.dataSelector': {
            deps: ['jquery'],
            exports: 'jquery.dataSelector'
        },

    },
    "exclude": [],
    "optimize": "none",
    "out": "built-base-modules.js"
}

А также base_module.js

define( function( require ) {

// Don't do anything with them.
// Just define them.

    require("jquery");
    require("k/kendo.core.min");
    //require("k/kendo.userevents.min");
    //require("kendoize/kendoize")
});

Я не уверен, связано ли это или нет, но трассировка зависимостей тоже не работает правильно. (Он успешно проследит один уровень глубиной, но не двумя уровнями глубины. Я попытался добавить core.min а также userevents.min вручную, чтобы увидеть, если это решило проблему.)

Кто-нибудь испытывал эту проблему с Кендо? Или, может быть, что-то подобное? Я проверил кучу существующих вопросов, но не нашел ничего связанного с этой настройкой.

Я могу опубликовать дополнительную информацию, если это необходимо, но подробное сообщение console.log не сработало где-то внутри require.js, а не из-за ошибки синтаксиса.

Дополнительная информация

HTML/Javascript на самой странице

    <script src="/Business/Scripts/require.js"></script>

<script>
    (function () {
        "use strict";

        var configObject = {
            shim: {
                'jquery.dataSelector': {
                    deps: ['jquery'],
                    exports: 'jquery.dataSelector'
                },
            },
            baseUrl: "http://760.j6.local:80/Business/Scripts",
                paths: {
                    app: "http://760.j6.local:80/Business",
                    k: "http://760.j6.local:80/Business" + "/Scripts/Frameworks/kendo-2013.1.514",
                    jquery: "http://760.j6.local:80/Business" + "/Scripts/Frameworks/jQuery/jquery.min",
                    jplugin: "http://760.j6.local:80/Business" + "/Scripts/Frameworks/jQuery",
                    f: "http://760.j6.local:80/Business" + "/Scripts/Frameworks/",
                }
            };

            requirejs.config(configObject);
        }());
</script>

    <script src="/Business/_build/built-base-modules.js"></script>

2 ответа

Решение

Я решил это.

Хотя Kendo поддерживает RequireJS, он использует 'require' - это динамический способ, который не очень удобен для оптимизатора.

Мое решение состояло в том, чтобы написать сценарий, который будет "разворачивать" сценарий, извлекать необходимые зависимости и затем записывать сценарий в новый файл.

var kendoFiles = ["kendo.autocomplete.min.js", "kendo.binder.min.js",
  "kendo.calendar.min.js", "kendo.colorpicker.min.js",
  "kendo.columnmenu.min.js", "kendo.combobox.min.js",
  "kendo.core.min.js", "kendo.data.min.js", "kendo.data.odata.min.js",
  "kendo.data.xml.min.js", "kendo.dataviz.chart.min.js",
  "kendo.dataviz.core.min.js", "kendo.dataviz.gauge.min.js",
  "kendo.dataviz.min.js", "kendo.dataviz.sparkline.min.js",
  "kendo.dataviz.stock.min.js", "kendo.dataviz.svg.min.js",
  "kendo.dataviz.themes.min.js", "kendo.dataviz.vml.min.js",
  "kendo.datepicker.min.js", "kendo.datetimepicker.min.js",
  "kendo.draganddrop.min.js", "kendo.dropdownlist.min.js",
  "kendo.editable.min.js", "kendo.editor.min.js",
  "kendo.filtermenu.min.js", "kendo.fx.min.js", "kendo.grid.min.js",
  "kendo.groupable.min.js", "kendo.imagebrowser.min.js",
  "kendo.list.min.js", "kendo.listview.min.js", "kendo.menu.min.js",
  "kendo.mobile.actionsheet.min.js",
  "kendo.mobile.application.min.js", "kendo.mobile.button.min.js",
  "kendo.mobile.buttongroup.min.js", "kendo.mobile.listview.min.js",
  "kendo.mobile.loader.min.js", "kendo.mobile.min.js",
  "kendo.mobile.modalview.min.js", "kendo.mobile.navbar.min.js",
  "kendo.mobile.pane.min.js", "kendo.mobile.popover.min.js",
  "kendo.mobile.scroller.min.js", "kendo.mobile.scrollview.min.js",
  "kendo.mobile.shim.min.js", "kendo.mobile.splitview.min.js",
  "kendo.mobile.switch.min.js", "kendo.mobile.tabstrip.min.js",
  "kendo.mobile.view.min.js", "kendo.multiselect.min.js",
  "kendo.numerictextbox.min.js", "kendo.pager.min.js",
  "kendo.panelbar.min.js", "kendo.popup.min.js",
  "kendo.reorderable.min.js", "kendo.resizable.min.js",
  "kendo.router.min.js", "kendo.selectable.min.js",
  "kendo.slider.min.js", "kendo.sortable.min.js",
  "kendo.splitter.min.js", "kendo.tabstrip.min.js",
  "kendo.timepicker.min.js", "kendo.tooltip.min.js",
  "kendo.touch.min.js", "kendo.treeview.min.js",
  "kendo.upload.min.js", "kendo.userevents.min.js",
  "kendo.validator.min.js", "kendo.view.min.js",
  "kendo.window.min.js"
];

var sourcePath = "../../Scripts/Frameworks/kendo-2013.1.514";
var destPath = "../../Scripts/kendo-rs";


function processFiles() {
  var i = -1;
  var l = kendoFiles.length;

  function nextStep() {
    i++;
    if (i < l) {
      var fileName = kendoFiles[i];
      processOne(fileName, nextStep);
    } else {
      console.log("All finished");
    }
  }
  nextStep();
}

function processOne(fileName, callback) {
  console.log("Processing: " + fileName);

  var fullName = sourcePath + "/" + fileName;
  fs = require('fs');
  fs.readFile(fullName, 'utf8', function (err, data) {
    if (err) {
      console.log(err);
    } else {
      getFileDependencies(fileName, data);
      callback();
    }
  });
}

function saveCode(fileName, code, moduleDependencies) {
  var fs = require('fs');

  var moduleDependenciesString = '"' + moduleDependencies.join('", "') +
    '"';

  var newCode = "define([" + moduleDependenciesString + "]," + "\r\n" +
    code + "\r\n" +
    ");";

  fs.writeFile(destPath + "/" + fileName, newCode, function (err) {
    if (err) {
      console.log(err);
    } else {
      console.log(fileName + " was saved!");
    }
  });
}

function getFileDependencies(fileName, code) {
  // * This is where the magic happens.
  // the kendo modules call define with the dependencies and the function.
  define = function (moduleDependencies, code) {
    for (i = 0; i < moduleDependencies.length; i++) {
      var str = moduleDependencies[i];
      str = str.replace("./", "k/");
      moduleDependencies[i] = str;
    }

    /// OPTIONAL STEP
    /// Set this to your jQuery path.  If you don't include jQuery globally,
    /// you run the risk of a race condition.
    moduleDependencies.push("jquery");

    console.log("Found dependencies: [" + moduleDependencies.join(":") +
      "]");
    saveCode(fileName, code, moduleDependencies);
  };
  define.amd = true; // Needed to make sure define gets called


  try {
    var z = eval(code);
  } catch (e) {
    // Yes, pokeman error handling...
    // We don't care if the code actually runs, so long as 'define' gets called.
  }
}


console.log("Starting");
processFiles();

У нас та же проблема, что и описанная: require.js + kendo + оптимизация, приводящая к той же самой ошибке после успешного процесса сборки.

Тем не менее, решение сверху не подходит мне, так как оно имеет дело с сторонним кодом. Я искал другое решение и обнаружил, что если я исключу кендо из сборки, оно все равно будет загружено во время выполнения. Я использую kendo.mobile.min.js, который включает в себя все зависимости и прекрасно сочетается с остальным проектом, который оптимизирован. В результате всего приложения нужно загрузить только 3 файла js: требовать, оптимизированную сборку и кендо.

Другими словами, если вы можете позволить себе загружать кендо как отдельный ресурс, добавьте следующее в конфигурацию сборки:

{
    baseUrl: "...",
    exclude: ['kendo.min'],
    include: ['jquery'],
(...)
}
Другие вопросы по тегам