Как импортировать XML-кодированный mxGraph в проект Webpack? - PullRequest
0 голосов
/ 11 июня 2018

Контекст

В рамках переноса большого проекта AngularJS / RequireJS в Webpack я рассмотрел различные части приложения и адаптировал зависимости, чтобы все работало.Ну, все, кроме mxGraph.

Проблема

Я не могу декодировать XML-кодированные графики.Я проследил проблему до mxCodec.prototype.decode, которая полагается на все функции, находящиеся в глобальной области, декодируя имена XML с помощью window[objectName], чтобы найти соответствующую функцию для создания экземпляров объектов.

Когда mxGraph загружается какВ модуле Webpack объекты не являются глобальными и не включены в объект window, следовательно, декодирование не работает.

Кроме того, приложение в значительной степени зависит от mxGraph и используется в различных модулях, поэтомуне может быть импортирован только в одном месте.

Кто-нибудь знает, как заставить это работать?

Заранее спасибо за вашу помощь.

Конфигурация

mxGraph импортируется с помощью загрузчика экспорта в Webpack, конфигурация которого выглядит примерно так:

rules: {
    test: path.resolve(__dirname, 'node_modules/mxgraph/javascript/mxClient.min.js'),
    use: [
      'exports-loader?' + [
        // handler
        'mxHandle', 'mxVertexHandler', 'mxEdgeSegmentHandler',

        // io
        'mxCodec', 'mxCodecRegistry',

        // layout
        'mxHierarchicalLayout', 'mxSwimlaneLayout',
        'mxCircleLayout', 'mxCompactTreeLayout', 'mxCompositeLayout', 'mxFastOrganicLayout', 'mxGraphLayout',
        'mxLayoutManager', 'mxParallelEdgeLayout', 'mxPartitionLayout', 'mxRadialTreeLayout', 'mxStackLayout',

        // model
        'mxCell', 'mxCellPath', 'mxGeometry', 'mxGraphModel',

        'mxClient',

        // shapes
        'mxActor', 'mxArrow', 'mxArrowConnector', 'mxCloud', 'mxConnector', 'mxCylinder', 'mxDoubleEllipse', 'mxEllipse', 'mxHexagon', 'mxLabel', 'mxLine',
        'mxMarker', 'mxPolyline', 'mxRectangleShape', 'mxRhombus', 'mxRubberband', 'mxStencil', 'mxStencilRegistry', 'mxSwimlane', 'mxText', 'mxTriangle',

        // util
        'mxConstants', 'mxEvent', 'mxUndoManager', 'mxUtils', 'mxDivResizer', 'mxImage', 'mxPoint', 'mxRectangle', 'mxLog',

        // view
        'mxGraph', 'mxEdgeStyle', 'mxCellRenderer', 'mxCellOverlay', 'mxCellState',
      ].join(','),
    ]
  }

, это уродливо, но позволяет приложению красиво импортировать mxGraph с синтаксисом, аналогичным import { mxArrow } from 'mx'.

Попытки

  • Я пытался решить эту проблему, оборачивая mxGraph в пользовательскую библиотеку "mxWrapper", которая переопределяет функцию mxCodec.prototype.decodeп, но это вызывает проблемы дальше по линии с ребрами, которые имеют контрольные точки.Возможно, мое переопределение не обрабатывает массивы mxPoint правильно ... но это решение кажется очень надуманным ...
  • Я также следовал этому шаблону безрезультатно

1 Ответ

0 голосов
/ 12 июня 2018

Я мог бы заставить его работать, следуя первой попытке, описанной выше, то есть написав свою собственную библиотеку "mxWrapper".Он придуман для такой простой необходимости, но он работает.

Основная идея:

import { 
  mxCell, mxCellPath, mxGeometry, mxGraphModel, mxCodec as _mxCodec, ...
} from 'mx';

// Overridden in our application
var mxCodec = _mxCodec;

var KNOWN_OBJECTS = {
  mxCell: mxCell,
  mxCellPath: mxCellPath,
  mxGeometry: mxGeometry,
  mxGraphModel: mxGraphModel,
  ...
  Array: Array,
  array: Array,
}

/**
 * Function: decode
 *
 * Decodes the given XML node. The optional "into"
 * argument specifies an existing object to be
 * used. If no object is given, then a new instance
 * is created using the constructor from the codec.
 *
 * The function returns the passed in object or
 * the new instance if no object was given.
 *
 * Parameters:
 *
 * node - XML node to be decoded.
 * into - Optional object to be decodec into.
 */
mxCodec.prototype.decode = function (node, into) {
  var obj = null;

  if (node != null && node.nodeType == mxConstants.NODETYPE_ELEMENT) {
    var ctor = null;

    try {
      ctor = KNOWN_OBJECTS[node.nodeName];
    }
    catch (err) {
      // ignore
    }

    var dec = mxCodecRegistry.getCodec(ctor);

    if (dec != null) {
      obj = dec.decode(this, node, into);
    }
    else {
      obj = node.cloneNode(true);
      obj.removeAttribute('as');
    }
  }

  return obj;
};


export {
  mxCell, mxCellPath, mxGeometry, mxGraphModel, ...
};

Я все еще очень открыт и заинтересован в лучших идеях ...

...