I am trying to implement yarn workspaces + lerna into my project. I have a simple structure:
--package.json
--node_modules/
--@app/
|--client/
|--package.json
|--node_modules/
|--server/
|--package.json
|--node_modules/
|--db/
|--package.json
|--node_modules/
Where client/ is a React-Native app. I am aware of the gotchas in react-native, and have modified my root /package.json
as follows:
"workspaces": {
"packages": [
"@app/*"
],
"nohoist": [
"**/react-native",
"**/react-native/**",
]
},
As I understand it, this should prevent react native itself, plus any of react-native's dependencies from being hoisted. However, what I am experiencing is that react-native libraries like react-native-linear-gradient
and react-native-reanimated
(which exist solely in client/package.json
) are being hoisted and installed at the root level node_modules
. It is not even just native modules that are hoisted. Javascript dependencies are also being hoisted:
Of course, the nohoist
option should not even come into play here, since these modules are only ever used within the client/
directory.
So then why would they be hoisted to the root?
For good measure, I have deleted the yarn.lock
files in each of my workspaces, keeping only the root level one. After running lerna clean
and rm -rf node_modules
, I have run yarn install
at the root level.
Interestingly, this install is very long (3-5 min). It even takes around 20s just to remove the root level node_modules
. I'm not at all sure if this is normal with yarn workspaces+lerna.
yarn version - 1.22.10
what I am experiencing is that react-native libraries like react-native-linear-gradient and react-native-reanimated (which exist solely in client/package.json) are being hoisted and installed at the root level node_modules
That's the intended behaviour, since they are not dependencies of react-native
. You would have to specify quite a bit of patterns like:
"nohoist": [
"**/react-native",
"**/react-native/**",
"**/react-native*",
"**/native-base",
"**/react-redux",
// OMG...
]
to match them all...
I actually would recommend to simply add this:
"workspaces": { "nohoist": "**" }
to the client/package.json
file.
This will cause all dependencies of the client
package to be installed in client/node_modules
– as if it was a standalone React Native project that doesn't have a Workspace at its parent.
Otherwise you would have to be constantly on guard when adding new packages in general (and especially native module packages) – did your nohoist
pattern reflect all the libraries you have added?
Also, there are issues with autolinking and hoisting.
On a more general and pathetic note, I'd say Yarn Workspaces' deduplication feature is overrated. It reduces disk space usage only marginally, and it might be simpler to just nohoist
everything and use Workspaces only for the case where it really shines – for easy local package linking.