Handle circular NPM package dependencies with Webpack
node_moduleswhich, on top of being semantically ugly, can make for really painful upgrades, as bumping the version of B in A and then releasing A should be followed by updating to this new version in B, and so forth... so what can we do to avoid this?
The quickest way to break the cycle is to remove A from B's
dependencies(or the other way around, depending on what makes the most sense) and add it to its
peerDependenciesinstead. It basically tells your package consumers that the latest compatible version of A should be installed alongside B for everything to work properly, without installing it directly: this transfers responsibility of maintaining the installed version of A onto them. You might also want to add A to B's
devDependenciesif its presence is necessary for tests to run properly, or anything else related to its maintenance. This should ease the pain within your dependency tree!
Finally, when developing A (which still explicitly depends on B), you might need to set things up so
importcalls targetting A resolve to your local code, the twin dependency not being around anymore. Doing so depends on your specific build setup, but it is pretty easy to do with Webpack thanks to the
resolvepart of its configuration:
// tell Webpack to look for third-party code in A's root directory before node_modules
modules: [__dirname, "node_modules"],
"A": __dirname // tell it to resolve A to this same directory
This example assumes your entry point (typically
index.js) lives in A's root directory; if it rather is is
src/, for example, you will want to use
Feel free to let me know of a better way to overcome such pitfalls when they cannot be avoided, if you know any!