Модули кендо и 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'],
(...)
}