rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

[RRFC] Allow set forbidden dependencies in package.json

Open harrisoff opened this issue 4 years ago • 8 comments

Motivation ("The Why")

Sometimes we can foresee that one day some dependencies will be needed in our projects, at that time, for some reasons (may be performances, vulnerabilities, compatibilities or event personal preferences) we want the maintainer (probably someone else) to use a specific dependency among dependencies with similar features.

We can mention it in the documents but it's hard to make sure every developer read carefully.

So it would be very helpful if it's possible to disable some dependencies in the project through package.json.

Example

If I'm going to use a time library, I would like to choose dayjs instead of moment. After I disable moment, when someone is trying to install it, the installation progress will be break and an error message will be thrown.

This feature will make it easier for the maintainers to control the deps the project will use.

How

Current Behaviour

Today there is no way to do this.

Desired Behaviour

The configure maybe like this:

// package.json
{
  // ...
  "disabledDependencies": {
    "moment": {
      "message": "Use dayjs instead"
    },
    "some-package": {
      "message": "some-package v4+ is not compatible with the existing package xxx, use v3 instead",
      "version": ">=4.0.0"
    }
  }
}

When trying to install the dependencies in the disabledDependencies, the installation progress will be break and an error will be thrown.

References

  • n/a

harrisoff avatar Aug 12 '21 06:08 harrisoff

(linking to https://github.com/npm/feedback/discussions/513)

ljharb avatar Aug 12 '21 06:08 ljharb

What happens if, as in this example, moment is a transitive dependency of something you're trying to install? What if it's a peer dep of something you're trying to install?

What should happen if you run npm install on an npm version that supports this disabling, with a lockfile generated by an npm version that doesn't?

ljharb avatar Aug 12 '21 06:08 ljharb

What happens if, as in this example, moment is a transitive dependency of something you're trying to install? What if it's a peer dep of something you're trying to install?

This is exactly my situation. I use ant-design in my project, and moment is its dependency.

In most cases we don't care how dependencies work, how their codes write, we only care about our codes. And most importantly it is impossible to check every dep's deps before using.

So disabling list should only work with explicitly installation. This should not be a strong restriction.

What should happen if you run npm install on an npm version that supports this disabling, with a lockfile generated by an npm version that doesn't?

I'm not sure what's your point. package.json and package-lock.json generated by an old npm version obviously will not have a disabledDependencies field, so npm install will goes fine, isn't it?

harrisoff avatar Aug 12 '21 08:08 harrisoff

package.json certainly could have it. That’s what i was asking tho - if the lockfile doesn’t agree with the package.json in npm 7.future (because npm 7.past generated it, and didn’t know about the new config), what should happen?

ljharb avatar Aug 12 '21 14:08 ljharb

Two drive-by suggestions:

  • forbiddenDependencies rather than disabledDependencies. Disabled often refers to something that is installed but not turned on (ie, a disabled extension in VSCode).
  • configurable for transitive dependencies as well via a {transitive: boolean} flag. Maybe the author of some-package ran over your dog and stole your bike, and you'd rather live peacefully knowing that you don't depend on that author. More realistically, maybe BigCorpA and BigCorpB are involved in some legal dispute whose outcome may make consumption of BigCorpB's package a problem for BigCorpA.

I like this rfc. It allows for some in-code assurances against some kinds of software bloat.

NiloCK avatar Aug 12 '21 19:08 NiloCK

Quite reasonable

harrisoff avatar Aug 13 '21 02:08 harrisoff

package.json certainly could have it. That’s what i was asking tho - if the lockfile doesn’t agree with the package.json in npm 7.future (because npm 7.past generated it, and didn’t know about the new config), what should happen?

I never thought about it... But based on my opinions:

  • disabling list should only work with explicitly installation (npm i xxx)
  • this should not be a strong restriction

I think if there are any conflicts, disabling list should be ignored.

harrisoff avatar Aug 13 '21 02:08 harrisoff

Bump

This became actual in times of "vibe codding". Code generator, always trying to install some libraries I don't want to use in project

TravnikovDev avatar Mar 09 '25 12:03 TravnikovDev