pnpm icon indicating copy to clipboard operation
pnpm copied to clipboard

Override peer dependency not work

Open Vampire2008 opened this issue 3 years ago • 12 comments

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/[email protected]": {
                "dependencies": {
                    "@pnp/common": "1.3.11",
                    "@pnp/odata": "1.3.11"
                }
            }
        }

Node.js: 14.18.2 OS: Windows

Vampire2008 avatar Jan 10 '22 09:01 Vampire2008

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.

bestickley avatar Jun 23 '22 20:06 bestickley

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

evelant avatar Sep 07 '22 15:09 evelant

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

nicolassanmar avatar Jan 16 '23 19:01 nicolassanmar

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

aspirisen avatar Jan 31 '23 10:01 aspirisen

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/[email protected] @pnp/[email protected]

zkochan avatar Feb 24 '23 02:02 zkochan

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.

kingyue737 avatar Feb 24 '23 02:02 kingyue737

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

{
  "pnpm": {
    "peerDependencyRules": {
      "allowedVersions": {
        "vite": "4"
      }
    }
  }
}

zkochan avatar Feb 24 '23 02:02 zkochan

@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

kingyue737 avatar Feb 24 '23 03:02 kingyue737

@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 avatar Jun 06 '23 03:06 tjx666

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;
        },
    },
};

tjx666 avatar Jun 06 '23 06:06 tjx666

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.

moltar avatar Jan 31 '24 22:01 moltar

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?

kylemh avatar Jun 22 '24 14:06 kylemh