Switch from yarn to npm; repair dependency graph #2576
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What
This PR does the following:
yarn.lock
, addpackage-lock.json
peerDependency
onreact
are all compatible with React 17.0.2 now, whereas before some only claimed to be compatible with React <= 16 or React >= 18).react-elastic-carousel
package.How did we get into a situation where the versions of our direct dependencies were incompatible with each other? Because of Yarn's dependency resolution strategy, which is looser and less predictable than you would hope. More details below.
Why
MapRoulette uses Yarn 1.x, which has been in maintenance mode since Jan 2020. Yarn 1.x uses dependency resolution strategy that is different from npm's, and leads to behavior that library authors do not expect, which ultimately means that many
@types
packages (containing Typescript type definitions) cannot be installed correctly. This is a blocker for any incremental adoption of Typescript in the MapRoulette codebase. It has also resulted in our dependency graph growing more and more corrupted over time - specifically, Yarn did not enforce that packages' peer dependency ranges were compatible with one another. Yarn 1.x also has numerous other unfixed issues (1, 2, 3).Yarn 2.x and above are radically different from Yarn 1.x. Modern versions of Yarn use a module installation strategy called Plug'n'Play in which there is no
node_modules
folder. Instead, Node, Typescript, Vite, and any other programs that load modules must be monkeypatched to resolve them through Yarn's.pnp.cjs
file. Frankly I think this decision is bizarre. Lots of tooling that we take for granted has reimplemented Node'snode_modules
resolution algorithm (from VSCode to typescript's language server to Github's dependabot) and throwing this away creates a ton of headaches.Yarn was originally created to address shortcomings in
npm
at the time: namely poor performance, no support for lockfiles, and limited support for workspaces (monorepos containing many JS packages which depend on each other; a common strategy for large libraries like Lodash or Turf). Butnpm
today has a local package cache (improving install speeds), and support for lockfiles and workspaces. It also has a new, much more sophisticated module resolution algorithm called Arborist.In short, there is no longer a compelling reason to stick with Yarn, and upgrading to a modern version of Yarn looks unappealing. The better choice IMO is to instead switch back to npm.
Todo
This PR is still a draft because there are a few issues left to deal with:
react-table
v6, which is incompatible with React 17. This is unfortunately a pain, becausereact-table
v7 (which is compatible with React 17) is a total rewrite. We use this dependency in a few different views; I think it's probably best to drop the dependency altogether and implement the functionality we need ourselves.yarn
withnpm
(e.g. in instructions about setting up the dev environment).yarn install
etc).