dnd-multi-backend icon indicating copy to clipboard operation
dnd-multi-backend copied to clipboard

DndProvider (new Api) cause Invariant Violation in production

Open Elendiar opened this issue 2 years ago • 7 comments

"react": "^18.2.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dnd-multi-backend": "^8.0.0",
"rdndmb-html5-to-touch": "^8.0.0",

I met with strange behavior, in the dev environment everything works with the new api, but in production there is an error Invariant Violation: Expected drag drop context. This happens with DndProvider (new API) usage only <DndProvider options={HTML5toTouch}>, but old one doesn't throw this error

import { DndProvider } from 'react-dnd'

 <DndProvider backend={MultiBackend} options={HTML5toTouch}>
...

This happens when i explicitly set react-dnd-html5-backend in package.json with updated yarn to 3.6.0 (because there is import { getEmptyImage } from "react-dnd-html5-backend"; in code.)

Before this DndProvider from 'react-dnd-multi-backend' worked without this error

Elendiar avatar Jun 07 '23 12:06 Elendiar

Hi @Elendiar,

This is similar to #92. Do you happen to have a minimal reproducible example I could use/test?

LouisBrunner avatar Jun 07 '23 13:06 LouisBrunner

You can reproduce this by creating a yarn monorepo (workspaces) with one app inside and install the following:

yarn workspace my-app add react-dnd react-dnd-html5-backend react-dnd-multi-backend react-dnd-touch-backend

The problem is that react-dnd-touch-backend uses react-dnd-preview which has a peer dependency of react-dnd.

This force somehow yarn to install react-dnd twice:

  1. /node_modules
  2. /apps/my-app/node_modules

And because react-dnd-multi-backend installed on the root (1), we get duplicate state of react-dnd.

Currently the only fix i found is to change the import path of react-dnd:

import { useDrag, useDrop } from 'react-dnd-multi-backend/../react-dnd';

I think that properly define peerDependencies for react-dnd-touch-backend will solve that, as you shouldn't use a library without declare it as a dependency.

moshest avatar Aug 22 '23 14:08 moshest

@moshest Thanks for adding more details to this but unfortunately this isn't enough for me to be able to reproduce the issue (I tried). Could you link to some demo repository I could build and try?

LouisBrunner avatar Aug 22 '23 17:08 LouisBrunner

I was able to reproduce it using the following setup:

  1. package.json:
{
  "name": "dnd-bug",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "private": true,
  "workspaces": [
    "apps/*"
  ],
  "devDependencies": {
    "@types/node": "20.4.4",
    "@types/react": "18.2.16",
    "@types/react-dom": "18.2.7"
  }
}
  1. apps/my-app/package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "private": true,
  "dependencies": {
    "@types/node": "20.4.4",
    "@types/react": "18.2.18",
    "@types/react-dom": "18.2.7",
    "react": "18.2.0",
    "react-dnd": "^16.0.1",
    "react-dnd-html5-backend": "^16.0.1",
    "react-dnd-multi-backend": "^8.0.1",
    "react-dnd-touch-backend": "^16.0.1",
    "react-dom": "18.2.0"
  }
}

Notice that @types/react has somehow different version number so it cause this all mess. I would expect only that package to be duplicated locally, but instead react-dnd got duplicated as well.

Syncing both versions of @types/react solve this problem.

moshest avatar Aug 26 '23 09:08 moshest

If the issue is with conflicting versions of @types/react then I am not sure if there is anything I can do to help? (maybe I am missing something?)

LouisBrunner avatar Aug 30 '23 09:08 LouisBrunner

I'm not an expert on Yarn/NPM, but I think using a dependency package should be mention on the package definition. Maybe not mentioning that react-dnd-multi-backend using react-dnd create those unexpected states.

There is a reason it's not listed on the peerDependencies?

moshest avatar Aug 30 '23 10:08 moshest

I released v8.0.2 which adds react-dnd as a peerDependency and it doesn't seem to change anything in the node_modules (not sure if that's a good test though).

LouisBrunner avatar Sep 06 '23 14:09 LouisBrunner