pnpm / pnpm

Fast, disk space efficient package manager
https://pnpm.io
MIT License
28.52k stars 954 forks source link

Override peer dependency not work #4214

Open Vampire2008 opened 2 years ago

Vampire2008 commented 2 years ago

pnpm version:

6.25.1

Code to reproduce the issue:

package.json:

{
  "dependencies": {
        "@pnp/common": "2.0.5",
        "@pnp/odata": "2.0.5",
        "@pnp/sp-clientsvc": "1.3.11"
  },
  "pnpm": {
      "overrides": {
          "@pnp/sp-clientsvc>@pnp/common": "1.3.11",
          "@pnp/sp-clientsvc>@pnp/odata": "1.3.11"
      }
  }
}

Some TypeScript file (some.ts):

import { ClientSvcQueryable } from '@pnp/sp-clientsvc';

export class MyQueryable extends ClientSvcQueryable {}

Expected behavior:

some.ts successfully compilled.

Actual behavior:

Compilation error:

error TS2515: Non-abstract class 'MyQueryable' does not implement inherited abstract member 'defaultAction' from class 'ClientSvcQueryable<any>'.

Additional information:

Error occured because there is in new @pnp/odata package new abstact methods.

@pnp/sp-clientsvc has @pnp/odata as peerDepedencies with exact versions. Also another package and code use new version of @pnp/odata and @pnp/common. Currently we are using Yarn, but we thinking about changing package manager. In Yarn we use resolutions property and it works as expected with peerDependencies.

"resolutions": {
        "@pnp/sp-clientsvc/@pnp/common": "1.3.11",
        "@pnp/sp-clientsvc/@pnp/odata": "1.3.11"
    }

Currenty I found workaround with "pnpm"."packageExtensions":

"packageExtensions": {
            "@pnp/sp-clientsvc@1.3.11": {
                "dependencies": {
                    "@pnp/common": "1.3.11",
                    "@pnp/odata": "1.3.11"
                }
            }
        }

Node.js: 14.18.2 OS: Windows

bestickley commented 2 years ago

I'm also experiencing an issue with pnpm.overrides. I'm trying to override pnpm to use a version of a package that's not vulnerable but it won't work. I add the override, run pnpm i, then run pnpm audit and still see the vulnerability.

evelant commented 1 year ago

Also facing this issue. I've got a conflicting minor peer dependency and overriding it does not stop pnpm from erroring.

nicolassanmar commented 1 year ago

I'm using pnpm version 7.25.0 and I have the same issue as @bestickley. The packages do not override the peer dependencies and it causes security vulnerabilities

aspirisen commented 1 year ago

I faced the same issue using version 7.26.2

Here is minimal example:

# package.json
{
  "name": "pnpm",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "pnpm": {
    "overrides": {
      "react": "16"
    }
  },
  "peerDependencies": {
    "react": "^16.9.0 || ^17.0.0 || ^18.0.0"
  }
}

#.npmrc
auto-install-peers=true
store-dir=.pnpm/store

Actual result: In node_modules I see react 18

Expected result: pnpm should take react version from overrides

zkochan commented 1 year ago

I don't understand why it is needed to override peer dependencies. You can just install the versions of peer dependencies that you want as dependencies of your project. Even if auto-install-peers is set to true, if you explicitly install a peer dependency in your project, that is the version that will be used. An override just isn't needed.

Package extensions are also not needed. In OP's case they just had to run:

pnpm add @pnp/common@1.3.11 @pnp/odata@1.3.11
kingyue737 commented 1 year ago

I use this feature to suppress warning. For example, vite-plugin-layout requires vite ^3.0.0 as a peer. If we have vite ^4.0.0 installed, pnpm will complain.

zkochan commented 1 year ago

So you just need to use the pnpm.peerDependencyRules.allowedVersions field:

{
  "pnpm": {
    "peerDependencyRules": {
      "allowedVersions": {
        "vite": "4"
      }
    }
  }
}
kingyue737 commented 1 year ago

@zkochan you are right. I reconfirmed and found I did use allowedVersions to suppress warning. I forgot why I subscribe this issue. Maybe I was looking for a method to replace an unmaintained peer dependency with my own fork. Sorry to bother you

tjx666 commented 1 year ago

@zkochan This is very counterintuitive. For a dependency used by 20+ workspace packages, I need to add the peer dependencies over 20 times. Things would be worse if exists many such peerdependencies

tjx666 commented 1 year ago

I use .pnpmfile.cjs to resolve this problem:

// https://github.com/pnpm/pnpm/issues/4214
const peerDependencies = ['peerDependency1', 'peerDependency2'];
const { overrides } = rootPkg.pnpm;
function overridesPeerDependencies(pkg) {
    if (pkg.peerDependencies) {
        for (const dep of peerDependencies) {
            if (dep in pkg.peerDependencies) {
                pkg.peerDependencies[dep] = overrides[dep];
            }
        }
    }
}

module.exports = {
    hooks: {
        readPackage(pkg, _context) {
            // skipDeps(pkg);
            overridesPeerDependencies(pkg);
            return pkg;
        },
    },
};
moltar commented 5 months ago

allowedVersions with scopes does not seem to work.

  "pnpm": {
    "peerDependencyRules": {
      "allowedVersions": {
        "@ws/my-ws-pkg>aws-cdk-lib": ">=2.100.0"
      }
    }
  },
packages/my-ws-pkg
├─┬ @aws-cdk/app-staging-synthesizer-alpha 2.123.0-alpha.0
│ └── ✕ unmet peer aws-cdk-lib@^2.123.0: found 2.100.0
└─┬ @aws-cdk/integ-tests-alpha 2.123.0-alpha.0
  └── ✕ unmet peer aws-cdk-lib@^2.123.0: found 2.100.0

Switching to this makes the error go away:

  "pnpm": {
    "peerDependencyRules": {
      "allowedVersions": {
        "aws-cdk-lib": ">=2.100.0"
      }
    }
  },

But the downside is too wide of an override. I only wanted to override for a single package.

kylemh commented 2 weeks ago

I don't understand why it is needed to override peer dependencies. You can just install the versions of peer dependencies that you want as dependencies of your project.

I don't like doing this because it doesn't signal intent. If somebody else evaluates dependencies, they will look at package.json and potentially find unused some unused dependency that I've installed in order to override a peerDep.

Additionally, the dep I install might not be in the relevant range. Think about dead dependencies that no longer keep deps up-to-date and the range of one of their peerDeps only supports insecure versions of a package.

In these scenarios, like trying to appease a security audit... what should one do? Additionally, does using a monorepo affect your answer?