Handle circular NPM package dependencies with Webpack
node_modules
which, 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 peerDependencies
instead. 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 devDependencies
if 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
import
calls 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 resolve
part of its configuration:{
resolve: {
// tell Webpack to look for third-party code in A's root directory before node_modules
modules: [__dirname, "node_modules"],
alias: {
"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 path.resolve(__dirname, "src")
instead.Feel free to let me know of a better way to overcome such pitfalls when they cannot be avoided, if you know any!