Debugging problems in a deeply nested javascript dependency
Tags: javascript, npm, node, typescript
Published: 2022-10-22 09:59:53

I was about to release a new patch version of the desktop app that I am working on and once the changes were ready, I decided to bump the npm version and do some final sanity checks
I first ran `npm i` and then `npm start`. And as I waited for the app launch, something felt off this time, and a quick look at the terminal showed what was wrong 


![nested dependency error after running `npm i`](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/glmym0v1vvu04xh3o4of.png)

`keyv`? This was not a package from my source code, and nor did I add any extra dependencies, so why now? what changed....

## What changed in the peer dependency? (*that I never knew I was using*)

I still don't completely know what this package does but that isn't important

`keyv` is a package that is used by `cacheable-request` which is used by the famous HTTP client `GOT`. `keyv` now provides its own type definitions, so you don't need @types/keyv package as a dev dependency anymore. 

Understandably, the [DefinatelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) team, one that maintains the `@type` modules, decided to remove the types for keyv since everything had been stable for a while now.
[The PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/62741) removes not just the `keyv` types but also it's reference inside the types of other packages that depended on it

But legacy projects that still either ran on node 14 (which does not easily provide support for the new ESM modules) or were just somehow using an older version of keyv as a nested dependency still needed @types/keyv 

My fixation on this random "patch-fix" of a probably unheard package, started not because I was using an old version of GOT, but rather an old version of electron builder, which in turn was using an old version of GOT

![npm module dependency tree](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eh1t4h4sd14mxtdm1ubc.png)

(_You see how deep this story goes!_)

The reason for the bug is obvious now if you know how typescript references types for modules. If the package does not have an `[filename].d.ts`, the file's type definition are not available. 
This was what DefinatelyTyped solved by providing the @types module. 
So the packages that still referenced this old @types/keyv module broke once [this PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/62741) was merged a few days back

## What actually went wrong?

So first of all this could be easily considered a breaking change and should not have been released as a patch version,
as pointed out in [this comment](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/62741#issuecomment-1284002918)

I think `cacheable-request`, which again I did not know we depended on, had "*" as the version for `keyv` in its `package.json`

So everyone ended up upgrading to this package and now everything breaks

## Solution: Pinning Dependency version
As mentioned in the referenced issue, you can pin the package to a particular version using [overrides](https://docs.npmjs.com/cli/v8/configuring-npm/package-json) inside package.json

```
"overrides" : {
    "@types/keyv": "3.1.4"
  },
```


But the better thing would be to just update all your dependencies. 

> If you haven't done this for some time now, something like [`npm-check-upgrades`](https://www.npmjs.com/package/npm-check-updates). I find myself referencing this article from freecodecamp every time I have to do so - https://www.freecodecamp.org/news/how-to-update-npm-dependencies/

---

TIL: "*" as a dependency version is a disaster waiting to happen. If not for you, then for the people using your code.