如何在 Webpack 项目中导入 XML 编码的 mxGraph?
How to import XML-encoded mxGraph in a Webpack project?
上下文
作为将大型 AngularJS / RequireJS 项目迁移到 Webpack 的一部分,我检查了应用程序的不同部分并调整了依赖关系,以便一切正常。好吧,除了 mxGraph。
问题
我无法解码 XML 编码的图表。我已将问题追溯到 mxCodec.prototype.decode
,它依赖于全局范围内的所有函数,使用 window[objectName]
解码 XML 名称以找到实例化对象的相关函数。
当 mxGraph 作为模块被 Webpack 加载时,对象不是全局的并且不包含在 window
对象中,因此解码不起作用。
此外,该应用程序对mxGraph的依赖性很强,并且在不同的模块中使用,因此不能只在一个地方导入。
有人知道如何让它工作吗?
预先感谢您的帮助。
配置
mxGraph 正在使用 Webpack 的 exports-loader 导入,配置与
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(','),
]
}
它很丑陋,但它允许应用程序使用 import { mxArrow } from 'mx'
.
的语法很好地导入 mxGraph
尝试次数
- 我试图通过将 mxGraph 包装在自定义 "mxWrapper" 库中来解决此问题,该库会覆盖
mxCodec.prototype.decode
函数,但这会导致问题进一步沿着具有控制点的边缘延伸。可能是我的重写没有正确处理 mxPoint 数组...但这个解决方案似乎很人为...
- 我也关注了this template没用
我可以按照上面描述的第一次尝试使它工作,即编写我自己的 "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, ...
};
我仍然非常开放并且对更好的想法很感兴趣...
上下文
作为将大型 AngularJS / RequireJS 项目迁移到 Webpack 的一部分,我检查了应用程序的不同部分并调整了依赖关系,以便一切正常。好吧,除了 mxGraph。
问题
我无法解码 XML 编码的图表。我已将问题追溯到 mxCodec.prototype.decode
,它依赖于全局范围内的所有函数,使用 window[objectName]
解码 XML 名称以找到实例化对象的相关函数。
当 mxGraph 作为模块被 Webpack 加载时,对象不是全局的并且不包含在 window
对象中,因此解码不起作用。
此外,该应用程序对mxGraph的依赖性很强,并且在不同的模块中使用,因此不能只在一个地方导入。
有人知道如何让它工作吗?
预先感谢您的帮助。
配置
mxGraph 正在使用 Webpack 的 exports-loader 导入,配置与
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(','),
]
}
它很丑陋,但它允许应用程序使用 import { mxArrow } from 'mx'
.
尝试次数
- 我试图通过将 mxGraph 包装在自定义 "mxWrapper" 库中来解决此问题,该库会覆盖
mxCodec.prototype.decode
函数,但这会导致问题进一步沿着具有控制点的边缘延伸。可能是我的重写没有正确处理 mxPoint 数组...但这个解决方案似乎很人为... - 我也关注了this template没用
我可以按照上面描述的第一次尝试使它工作,即编写我自己的 "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, ...
};
我仍然非常开放并且对更好的想法很感兴趣...