Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Workspaces hoisted package is not resolving to dependent's peer dependencies #2989

Open
ruluva opened this issue Mar 30, 2021 · 1 comment
Labels
Bug thing that needs fixing Release 7.x work is associated with a specific npm 7 release

Comments

@ruluva
Copy link

ruluva commented Mar 30, 2021

Current Behavior:

I have a project using multiple workspaces. For simplicity I created a smaller project that reproduces the issue.
I am using @testing-library/react to help with some unit tests, and I have pulled in the required peer dependencies of react and react-dom. Each package is using its own version of React, one is using 17.0.1 and the other 17.0.2. Both are using the same @testing-library/react package version. The hoisted packages are react (17.0.2), react-dom (17.0.2) and @testing-library/react (11.2.5). Package b has its own React versions for react and react-dom in its local node_modules. I have both projects using the @testing-library/react render function in a set of test files. When I run jest on project a, it passes without issue. When I run jest on project b (with its local versions), it fails with the following error:

[email protected] test
jest

FAIL tests/components/App.test.tsx
● Console

console.error
  Error: Uncaught [Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app
  See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.]
      at reportException (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:62:24)
      at innerInvokeEventListeners (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:341:9)
      at invokeEventListeners (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
      at HTMLUnknownElementImpl._dispatch (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
      at HTMLUnknownElementImpl.dispatchEvent (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
      at HTMLUnknownElement.dispatchEvent (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
      at Object.invokeGuardedCallbackDev (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:3994:16)
      at invokeGuardedCallback (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:4056:31)
      at beginWork$1 (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:23964:7)
      at performUnitOfWork (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:22779:12) Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app
  See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
      at resolveDispatcher (/Users/USER_DIRECTORY/experimental/npm-workspaces/packages/package-b/node_modules/react/cjs/react.development.js:1476:13)
      at Object.useState (/Users/USER_DIRECTORY/experimental/npm-workspaces/packages/package-b/node_modules/react/cjs/react.development.js:1507:20)
      at App (/Users/USER_DIRECTORY/experimental/npm-workspaces/packages/package-b/src/components/App.tsx:10:29)
      at renderWithHooks (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:14985:18)
      at mountIndeterminateComponent (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:17811:13)
      at beginWork (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:19049:16)
      at HTMLUnknownElement.callCallback (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:3945:14)
      at HTMLUnknownElement.callTheUserObjectsOperation (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
      at innerInvokeEventListeners (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:338:25)
      at invokeEventListeners (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
      at HTMLUnknownElementImpl._dispatch (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
      at HTMLUnknownElementImpl.dispatchEvent (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
      at HTMLUnknownElement.dispatchEvent (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
      at Object.invokeGuardedCallbackDev (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:3994:16)
      at invokeGuardedCallback (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:4056:31)
      at beginWork$1 (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:23964:7)
      at performUnitOfWork (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:22779:12)
      at workLoopSync (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:22707:5)
      at renderRootSync (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:22670:7)
      at performSyncWorkOnRoot (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:22293:18)
      at scheduleUpdateOnFiber (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:21881:7)
      at updateContainer (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:25482:3)
      at /Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:26021:7
      at unbatchedUpdates (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:22431:12)
      at legacyRenderSubtreeIntoContainer (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:26020:5)
      at Object.render (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:26103:10)
      at /Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/@testing-library/react/dist/pure.js:99:25
      at batchedUpdates$1 (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom.development.js:22380:12)
      at act (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14)
      at Object.render (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/@testing-library/react/dist/pure.js:95:26)
      at Object.<anonymous> (/Users/USER_DIRECTORY/experimental/npm-workspaces/packages/package-b/tests/components/App.test.tsx:5:29)
      at Object.asyncJestTest (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:106:37)
      at /Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jest-jasmine2/build/queueRunner.js:45:12
      at new Promise (<anonymous>)
      at mapper (/Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jest-jasmine2/build/queueRunner.js:28:19)
      at /Users/USER_DIRECTORY/experimental/npm-workspaces/node_modules/jest-jasmine2/build/queueRunner.js:75:41
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  at VirtualConsole.<anonymous> (../../node_modules/jsdom/lib/jsdom/virtual-console.js:29:45)
  at reportException (../../node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:28)
  at innerInvokeEventListeners (../../node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:341:9)
  at invokeEventListeners (../../node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
  at HTMLUnknownElementImpl._dispatch (../../node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
  at HTMLUnknownElementImpl.dispatchEvent (../../node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
  at HTMLUnknownElement.dispatchEvent (../../node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)

console.error
  The above error occurred in the <App> component:
  
      at App (/Users/USER_DIRECTORY/experimental/npm-workspaces/packages/package-b/src/components/App.tsx:10:29)
  
  Consider adding an error boundary to your tree to customize error handling behavior.
  Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

  at logCapturedError (../../node_modules/react-dom/cjs/react-dom.development.js:20085:23)
  at update.callback (../../node_modules/react-dom/cjs/react-dom.development.js:20118:5)
  at callCallback (../../node_modules/react-dom/cjs/react-dom.development.js:12318:12)
  at commitUpdateQueue (../../node_modules/react-dom/cjs/react-dom.development.js:12339:9)
  at commitLifeCycles (../../node_modules/react-dom/cjs/react-dom.development.js:20736:11)
  at commitLayoutEffects (../../node_modules/react-dom/cjs/react-dom.development.js:23426:7)
  at HTMLUnknownElement.callCallback (../../node_modules/react-dom/cjs/react-dom.development.js:3945:14)
  at HTMLUnknownElement.callTheUserObjectsOperation (../../node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)

● Testing render

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

   8 | export const App = (props: AppProps): JSX.Element => {
   9 |   // Create the count state.
> 10 |   const [count, setCount] = useState(0);
     |                             ^
  11 |   const [user, setUser] = useState<string>();
  12 |
  13 |   // Create the counter (+1 every second).

  at resolveDispatcher (node_modules/react/cjs/react.development.js:1476:13)
  at Object.useState (node_modules/react/cjs/react.development.js:1507:20)
  at App (src/components/App.tsx:10:29)
  at renderWithHooks (../../node_modules/react-dom/cjs/react-dom.development.js:14985:18)
  at mountIndeterminateComponent (../../node_modules/react-dom/cjs/react-dom.development.js:17811:13)
  at beginWork (../../node_modules/react-dom/cjs/react-dom.development.js:19049:16)
  at HTMLUnknownElement.callCallback (../../node_modules/react-dom/cjs/react-dom.development.js:3945:14)
  at HTMLUnknownElement.callTheUserObjectsOperation (../../node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
  at innerInvokeEventListeners (../../node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:338:25)
  at invokeEventListeners (../../node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
  at HTMLUnknownElementImpl._dispatch (../../node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
  at HTMLUnknownElementImpl.dispatchEvent (../../node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
  at HTMLUnknownElement.dispatchEvent (../../node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
  at Object.invokeGuardedCallbackDev (../../node_modules/react-dom/cjs/react-dom.development.js:3994:16)
  at invokeGuardedCallback (../../node_modules/react-dom/cjs/react-dom.development.js:4056:31)
  at beginWork$1 (../../node_modules/react-dom/cjs/react-dom.development.js:23964:7)
  at performUnitOfWork (../../node_modules/react-dom/cjs/react-dom.development.js:22779:12)
  at workLoopSync (../../node_modules/react-dom/cjs/react-dom.development.js:22707:5)
  at renderRootSync (../../node_modules/react-dom/cjs/react-dom.development.js:22670:7)
  at performSyncWorkOnRoot (../../node_modules/react-dom/cjs/react-dom.development.js:22293:18)
  at scheduleUpdateOnFiber (../../node_modules/react-dom/cjs/react-dom.development.js:21881:7)
  at updateContainer (../../node_modules/react-dom/cjs/react-dom.development.js:25482:3)
  at ../../node_modules/react-dom/cjs/react-dom.development.js:26021:7
  at unbatchedUpdates (../../node_modules/react-dom/cjs/react-dom.development.js:22431:12)
  at legacyRenderSubtreeIntoContainer (../../node_modules/react-dom/cjs/react-dom.development.js:26020:5)
  at Object.render (../../node_modules/react-dom/cjs/react-dom.development.js:26103:10)
  at ../../node_modules/@testing-library/react/dist/pure.js:99:25
  at batchedUpdates$1 (../../node_modules/react-dom/cjs/react-dom.development.js:22380:12)
  at act (../../node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14)
  at Object.render (../../node_modules/@testing-library/react/dist/pure.js:95:26)
  at Object.<anonymous> (tests/components/App.test.tsx:5:29)

So the @testing-library/react packages seems to be referencing the root level React versions, which cause an issue with the local versions.

Expected Behavior:

I expected the @testing-library/react to reference the workspace specific React versions.

Steps To Reproduce:

Package A package.json:
"dependencies": {
"react": "17.0.2",
"react-dom": "17.0.2",
},
"devDependencies": {
"@testing-library/react": "11.2.5",
"react-test-renderer": "17.0.2",
}

Package B package.json
"dependencies": {
"react": "17.0.1",
"react-dom": "17.0.1",
},
"devDependencies": {
"@testing-library/react": "11.2.5",
"react-test-renderer": "17.0.1",
}

And I created a very simple test for each package:

import { render } from '@testing-library/react';
import { App } from '../../src/components/App';

test('Testing render', () => {
const renderedElement = render();

expect(renderedElement).toBeDefined();

});

Environment:

OS: MacOS 11.2.3
Node: 14.15.4
npm: 7.7.5

@ruluva ruluva added Bug thing that needs fixing Needs Triage needs review for next steps Release 7.x work is associated with a specific npm 7 release labels Mar 30, 2021
@ruluva ruluva changed the title [BUG] Worspaces hoisted package is not resolving to dependent's peer dependencies [BUG] Workspaces hoisted package is not resolving to dependent's peer dependencies Apr 2, 2021
@darcyclarke
Copy link
Contributor

@ruluva appreciate you filing this; We've had some other feedback around this kind of scenario & have started to consider enhancements/options to resolve this in a nice way (ref: see this drafted PR in our npm/rfcs repo). In the meantime, you can work around this problem by using either --legacy-bundling or the --global-style flags to help nest your deps & ensure they don't conflict (this, unfortunately, means many deps won't be deduped across your workspaces - again, we're working on a solution for that)

@darcyclarke darcyclarke removed the Needs Triage needs review for next steps label May 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug thing that needs fixing Release 7.x work is associated with a specific npm 7 release
Projects
None yet
Development

No branches or pull requests

2 participants