Skip to content
This repository has been archived by the owner on Jun 11, 2020. It is now read-only.

Broken by unconstrained DefinitelyTyped dependencies #360

Open
octogonz opened this issue Jul 1, 2017 · 2 comments
Open

Broken by unconstrained DefinitelyTyped dependencies #360

octogonz opened this issue Jul 1, 2017 · 2 comments

Comments

@octogonz
Copy link

octogonz commented Jul 1, 2017

My project failed to compile today because a new version of @types/bluebird was published. This new version uses keywords that are a syntax error unless you have a TypeScript compiler version >2.3 or newer.

(We want to use the latest TypeScript compiler, but upgrading is an expensive process for us. We have a *lot* of projects and source code, so we cannot migrate compilers as quickly as other people.)

The obvious solution is to lock @types/bluebird to an older version for the time being. However, we have no explicit dependency on @types/bluebird. (In fact, our coding standards ask people to use ES6 standard promises instead of proprietary libraries like Bluebird.)

It turns out that we get @types/bluebird as a dependency of @types/karma. Karma's version is locked, but the @types/karma package.json has unconstrained dependencies like this:

  "dependencies": {
    "@types/bluebird": "*",
    "@types/log4js": "*",
    "@types/node": "*"
  },

I was surprised when I saw this. We never use caret/tilde for @types packages, because DefinitelyTyped does not follow SemVer. (Instead, DefinitelyTyped typings aim to match the major/minor version of the underlying package. Patch number increments can and do break the contract, e.g. if a TypeScript interface got renamed or redesigned, which is not part of the underlying JavaScript API contract.)

Thus, I find it really strange that DefinitelyTyped doesn't lock its package dependency versions. I'm guessing the idea behind this policy is to avoid side-by-side versions at all costs. But does this approach actually accomplish that goal? Instead, it seems to force consumers to adopt two rules instead of one:

  1. In our package.json files, never use caret/tilde with @types dependencies
  2. Always explicitly include the transitive closure of any indirect @types dependencies, to avoid getting burned by the "*"

This may be a worse outcome than if DefinitelyTyped simply locked the versions for us.

@octogonz
Copy link
Author

octogonz commented Jul 1, 2017

Some people suggested that we could use npm-shrinkwrap.json/package-lock.json to lock down our indirect dependencies. We actually do this already. It doesn't help:

In general, it's not safe for people to manually edit a shrinkwrap file, because it represents a solution to a complicated versioning equation. Instead, people should delete the shrinkwrap file, upgrade the node_modules folder, and then create a new shrinkwrap file. When upgrading the node_modules folder, it is not obvious how to fix one dependency like @types/bluebird, and in the worst case (e.g. for a side-by-side indirect dependency) the NPM tooling may not provide any way to fix it. Usually we just delete the whole node_modules folder and reinstall it to upgrade everything at once.

(We have a lot of projects, so we can't expect people to figure out special solutions for each package. We need an approach that is easy to explain and works for all cases.)

@blakeembrey
Copy link

You may be interested in #12.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants