Created by: yhnavein
Hi,
Let me describe briefly our situation first.
We are using React applications generated by CRA and we have a separate repository with components. This component repository is a monorepo handled for us by lerna (with yarn workspaces). Typescript is used everywhere. All components are having only peerDependencies
- no dependencies
.
This set up works pretty decently, but we struggled with strange issues when at least one component from monorepo is yarn linked into the CRA app. Linking components is an essential feature for us.
The problem appeared firstly by broken styled-components
in our app and message that multiple instances of styled-components
package being in use at once and indeed there were multiple occurences of this package (and others too). Using a bundler in component's code and defining external packages does have no effect.
Following PR contains a fix for our problem. While doing an investigation we found that other approach of a fix was already proposed (https://github.com/facebook/create-react-app/pull/5654), but sadly forgotten. And those 2 ways are generally very similar.
The problem is that in case of linked components, symlinks are created and by default Webpack resolves them as real paths. It means that while analyzing our custom package from monorepo, webpack is looking for dependent modules by going up and up in the folder hierarchy, but because it's a symlinked location he won't hit node_modules
of our application first, but node_modules
of the root of the component's monorepo. Webpack will include this is the bundle and moves on. Later webpack will hit our application's use of the problematic 3rd party lib, will do the same but it will reach app's node_modules
and tadam - we have multiple versions of basically the same lib bundled. I hope that I understood and explained it well :)
Turning off symlinks is one way. We changed slightly a module resolution by the webpack using a full path to application's node_module
first. In our opinion it is less a breaking change. Optionally I can introduce an env variable that would prevent this from being a breaking change at all.
Topic is open for discussion.
Thanks