I'm attempting to define a custom connector in JointJS in Vue. Though I don't think this is really a JointJS issue or a Vue issue, but rather my lack of understanding of how Javascript modules work in this context...
I have this code, which seems to match the docs (https://resources.jointjs.com/docs/jointjs/v3.3/joint.html#connectors.custom):
import Vue from 'vue';
let joint = Vue.joint;
joint.connectors = joint.connectors || {};
joint.connectors.CloudConflictConnector = function(sourcePoint, targetPoint, vertices, args)
{
...
}
Note that Vue.joint is created as a plugin, this way:
const Joint = {
install: function (Vue) {
let joint = { g, dia, layout, linkTools, V };
Object.defineProperty(Vue.prototype, '$joint', { value: joint });
Vue.joint = Vue.prototype.$joint;
}
};
Vue.use(Joint);
But when I later attempt to use this connector, findPath()
in JointJS throws an error that the connector doesn't exist. The issue appears to be that in findPath
, it's importing the connectors module from the npm package. That module obviously doesn't have anything I added to the Vue.joint.connectors
property.
If I try to add the function to the module more directly, I get a 'Object is not extensible' error. For example doing something like this in the plugin instead:
import * as connectors from 'jointjs/src/connectors/index.mjs';
const Joint = {
install: function (Vue) {
let joint = { g, dia, layout, linkTools, V, connectors };
joint.connectors.customConnector = ...;
Object.defineProperty(Vue.prototype, '$joint', { value: joint });
Vue.joint = Vue.prototype.$joint;
}
};
Vue.use(Joint);
So I guess the question is how does one properly add a property to a module export in a way that other code that imports the module directly can still see it? I think outside Vue, this would all just work because joint
would be a global variable (?)
Part of the problem is the plugin creates a new joint
object, which is missing the original import's connectors
property.
However, I believe the plugin should keep the original import and setup the custom connector on that:
export default {
install(app) {
const joint = require('jointjs')
addCustomConnector(joint)
app.prototype.$joint = joint
app.joint = joint
}
}
function addCustomConnector({ connectors }) {
connectors.CloudConflictConnector = (sourcePoint, targetPoint, vertices, args) => {
//...
}
}