/node_modules/ directory and grab react from there.īut OH NOES, that code won't work at runtime because the code written in bar needs that fancy new feature in React 16.13! This is a problem that is also nicely summed up in the Rush docs as a " Phantom Dependency" and a " Doppleganger". What's gonna happen? Welp, because of the fact that bar doesn't have a react in its package.json, the node module resolution algorithm will kick in and look up to the. Then, let's say over in bar, they forgot to add react in the package.json, but in bar/src/index.ts someone does an import React., and it also happens that bar used a feature that only exists in the 16.13.0 version of React. Let's say the foo/package.json has "react": "^16.9.0". Well, a couple of different bad things can happen here. Ok, so that seems fine, where can we go wrong here? node_modules directory and see if it's there. packages/node_modules/, which definitely should not be there, and then it'll look at the. įollowing the node module resolution from above, it'll eventually look in the. packages/foo/ and it does an import React from 'react'. So, most monorepo structures have a root package.json, and a packages folder./packages/foo/ packages/*/node_modules/react for the 3 cases of 16.13.0. That way you don't have to have 50 different versions of react in your project, the import React or require('react') calls will simply pull from the root node_modules/react one in the case of 16.9.0, or. If you have 50 packages, and 47 of them are using react 16.9.0, but 3 are using 16.13.0, it'll "hoist" the common version of react, 16.9.0 to the top level. What this hoisting does is, it scans your package.json files across your workspaces and figures out what the most common versions of dependencies are. Package managers such as yarn and npm implemented a hoisting algorithm as a part of their different workspaces implementations. If you do require('X') and it's not a node thing, then keep traversing the file system looking in every node_modules along the way. If you start require('/X') you're at the file system root. If you require X, see if it exists in node, things like fs, child_process, etc. If you take a read through the docs, you'll find this. Let's take a step back for a sec and take a look at what happens when you require something. That problem is even more massive in a large monorepo. What's this hoisting thing?Īs we all know, node_modules is a deep dark place with lots and lots of stuff. One of the most painful cons, when it comes to working in a specifically JavaScript based monorepo, is the pain that comes from hoisting. Working in a monorepo comes with a long list of pros, and a few cons.
0 Comments
Leave a Reply. |