kutlugsahin / smooth-dnd

drag and drop library for javascript
MIT License
615 stars 148 forks source link

Conflict when smooth-dnd is used by two libraries on same page #74

Open tstecca opened 4 years ago

tstecca commented 4 years ago

Hello kutlugsahin,

Thank you for providing the javascript community with this excellent library.

We maintain a web-based content management system that uses vue-smooth-dnd to create a table of contents of available pages of content. Coincidentally, a small number the content pages loaded by the CMS also use vue-smooth-dnd to create some draggable effects.

Both the CMS and the content pages are separate javascript files, but they happen to be running on the same page. The table of contents loads well, but then the content pieces containing smooth-dnd load, the second library throws:

TypeError: Illegal invocation
    at Node.get (vendors.js:139403)
    at [USER]\repos\global-web-assets-3\node_modules\smooth-dnd\dist\index.js:1
    at [USER]\global-web-assets-3\node_modules\smooth-dnd\dist\index.js:1
    at Object.../node_modules/smooth-dnd/dist/index.js ([USER]\repos\global-web-assets-3\node_modules\smooth-dnd\dist\index.js:1)
    at __webpack_require__ (bootstrap:1480)
    at fn (bootstrap:832)
    at Module.../node_modules/vue-smooth-dnd/dist/vue-smooth-dnd.esm.js ([USER]\repos\global-web-assets-3\node_modules\vue-smooth-dnd\dist\vue-smooth-dnd.esm.js:1)
    at __webpack_require__ (bootstrap:1480)
    at fn (bootstrap:832)
    at Module.../node_modules/babel-loader/lib/index.js!../node_modules/vue-loader/lib/index.js?!./components/bs-v1/component.vue?vue&type=script&lang=js& 

This error prevents the vue-smooth-dnd content elements from functioning. I have seen this issue else where in the issue tracker for this repo, like in issue #36 . The recommended solution was adding this code before vue-smooth-dnd is imported.

    Object.defineProperty(global, 'Node', {
      value: { firstElementChild: 'firstElementChild' }
    })

This actually cleared the error for me, but led to another set of errors:

Uncaught TypeError: Cannot read property 'getOptions' of undefined at HTMLDocument.Ve 
Uncaught TypeError: Cannot read property 'draggables' of undefined
    at ~\node_modules\smooth-dnd\dist\index.js:1

My first guess is that the first instance of smooth-dnd is modifying the global Node object in a way that makes it unusable for the second instance. I realize that this is an usual use case, but I was hoping you could offer some guidance. I hoping to avoid re-authoring one of these applications without smooth-dnd.

Thanks for your help.

sean9keenan commented 4 years ago

I don't have much to add here - but I encountered this issue, and was fortunate enough that I had control of all of the libraries in question, so I was able to re-export my react-smooth-dnd from the child library to be re-used by the parent. (Not a real solution - but might help someone finding this thread).

More relevantly - I found that having

Object.defineProperty(global, 'Node', {
  value: { firstElementChild: 'firstElementChild' }
})

Leads to the other set of errors you posted, even when there is only one instance of smooth-dnd imported (although perhaps I was importing this in the wrong order). So the fix for jest (like in #36) seems specific to jest insofar as "it'll work" if getOptions and draggables are not used anywhere in the test suite (this is a guess, since I don't have jest set up).

tstecca commented 4 years ago

sean9keenan, That's a good idea. I should have tried that. We ended up switch one of our projects to Vue Draggable to avoid the conflicts.