Kendo Modules and RequireJS (r.js) not playing nice. (Error on loading)

空扰寡人 提交于 2019-12-06 03:43:27

I solved it.

While Kendo does support RequireJS, it uses the 'require' is a dynamic way that is not very friendly to optimizer.

My solution was to write a script that would "unwrap" the script, extract out the needed dependencies and then write the script into a new file.

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();

We have the same problem as described: require.js + kendo + optimization resulting in the very same error after a successful build process.

However, the solution from above does not suite me well as it deals with 3rd party code. I looked for another solution and I found out that if I exclude the whole kendo from the build it will be still downloaded at runtime. I use kendo.mobile.min.js which includes all dependencies and plays nicely with the rest of the project, which is optimized. As a result the whole app needs to download just 3 js files: require, optimized build and kendo.

In other words, if you can afford loading kendo as a separate resource, add the following to the build config:

{
    baseUrl: "...",
    exclude: ['kendo.min'],
    include: ['jquery'],
(...)
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!