Better package management with npm
How can npm help you remove unmaintained packages from a big repo?
You can use
npm i <wrapper-old-package> --global-style to prevent your teammates from accidentally importing
One of many approaches to removing a package from a big project that many developers contribute to, is to
- Keep existing functionality that rely on this package.
- Prevent these developers from relying on the package in focus.
In this short writing, we are going to look at how npm can help us achieve these two processes.
We are going to use Momentjs as an example since it is popular and its maintainers discourage its usage.
We will also be using
Below is the structure of our sample repo
index.mjs contains one function that calculates remaining time using Momentjs
package.json contains entry for Momentjs as a dependency.
Keep existing functionality that rely on Momentjs.
Let us do some refactoring so that our
calculateRemainingTime function is moved to a workspace (
wrapper-moment), then have the root level
index.mjs import this function from that workspace.
Now, our new repo should look like below.
Prevent developers from relying on Momentjs.
At this point, we still have Momentjs inside the root level
Let us run these two commands to move Momentjs inside the workspace’s
npm uninstall moment
npm install moment --global-style --workspace=wrapper-moment
--global-style will ensure that Momentjs is only accessible inside the workspace. Therefore, importing it from the root level
index.mjs should trigger an error.
We can also verify that moment is indeed now just part of the
wrapper-moment package by running
npm explain moment.
Why does this approach work?
Npm default installation process
npm cli implements a
maximally naive deduplication algorithm, which seeks to minimize the number of duplicated packages.
It does this by generating the shortest tree possible, which in turn forces many packages to become direct children of the root level
Node Module Resolution
Nodejs looks for the closest
node_modules folder to resolve a module.
Therefore, if a package was installed because of an inner dependency, then Nodejs is going to pick it up, even if the project does not intend to rely on it directly.
--global-style will help prevent the unintended module resolution.
Npm has evolved into an all purpose solution that allows developers to achieve almost any package management process they want.