'NPM 7 Workspaces installing multiple versions of react
We have a mono-repo that I'm migrating to npm 7's workspaces.
Current folder org:
\React
- package.json (defines workspaces for \apps and \packages)
\apps
\someApp
- React 17.0.1 (Dependency)
\otherApp
\packages
\component-library
- React 16.14.0 || 17.0.0 (Peer)
- Storybook (6.1)
- Storybook MUI Add On
\framework
- React 16.14.0 || 17.0.0 (Peer)
Running npm ci in the React folder installs React 16.14 in the \React\node_modules and 17.0.0 in \React\apps\someApp\node_modules. When trying to run the app we get the expected hook error due to multiple versions being installed. But I can't find anything that is explicitly requiring React 16.14?
Solution 1:[1]
The specific issue in the question looks like it may have been one of the many arborist bugs in early(ish) versions of NPM 7 - in NPM 8 and beyond, it should see that React 17 is supported by everything, and should therefore choose that.
For anyone with similar issues with more recent versions of NPM - in NPM >=8.3.0 you can use overrides to force a particular version.
Important notes:
overridesmay only be set in the repo's rootpackage.json, not individual workspacepackage.jsonfiles.- You might need to flush node_modules and package-lock.json after adding overrides (hopefully fixed soon by the fix to this issue)
- It's your responsibility to ensure that the overrides you apply don't break things: many packages with a
"react": "^16.x.x"dependency are in reality compatible with React 17 and just haven't been updated, but not all; some may be legitimately not compatible with React 17. Be careful and look for issues on the repos of the packages whose"^16.x.x"dependencies you are overriding. There may even be a new version or alternative you can apply that does directly support React 17. - You may also need to override
react-domas well asreactto ensure the two can't get out of sync.
Something like this should work in a root package.json:
"overrides": {
"react": "^17.0.1",
"react-dom": "^17.0.1",
}
Solution 2:[2]
If you're using webpack, and your configuration was semi-based on create-react-app, you can tweak the modules paths, at least this works for me:
modules: [path.join(__dirname, '../node_modules'), 'node_modules', paths.appNodeModules].concat(modules.additionalModulePaths || []),
assuming your webpack.config.js is in apps/someapp/config directory
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | user56reinstatemonica8 |
| Solution 2 | Rob Elsner |
