I have a fairly standard lerna monorepo that will look like this:
packages/
main/ - This is the main deployable application, it depends on both dep and react-dep
dep/ - Just some pure functions, no problems here
react-dep/ - A design system built with react, this is where we have problems.
So a really common problem that happens, is as soon as you start using hooks in your dependency library, you get this message:
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/warnings/invalid-hook-call-warning.html for tips about how to debug and fix this problem.
Which is because there are two version of React in your app, one from the main application, and one from the dependency.
Now - a common solution, that I've used, and works, is to declare react
and any other shared/peer dependencies as externals
in your webpack configuration. Eg, as suggested here. or look at this Github issues thread from react.
However, I'm not a fan of this solution, firstly, what if I'm not using webpack, and secondly I shouldn't have to manually keep track of which dependencies I need to mark as external.
I think what should work is:
In react-dep
I declare react
in both devDependencies
and peerDependencies
. The reason I put it in devDependencies
is because my dependency library is likely using storybook or similar to develop the components, so I do need react around in development.
I think that this should work if I'm publishing react-dep
to npm and consuming the compiled code from npm in main
, because only dependencies
are going to be fetched.
However, I think due to the lerna symlinking, what happens in this case is that the dev dependency is still around and we get this error.
Is there a way to solve this issue for a lerna monorepo?
Here's github repo that demonstrates this issue: https://github.com/dwjohnston/lerna-react-monorepo