Repository navigation
fix: prune optional peer dependencies that are no longer explicitly depended on - #8431
Conversation
Yeah this is a GOOD thing cause answering this question will help us know if this PR is right. |
|
@wraithgar so I've spent a few hours trying to dig into this without much luck, though I'm still pretty sure the failure is about the test setup rather than the fix being wrong - if I revert the fix, then all the tests fail with the same kind of error though there's more of them because it's resolving about 20 more packages. I think the issue is something on the lines of dependencies (not) being cached - the error gets raised when calling this: cli/workspaces/arborist/lib/arborist/reify.js Lines 799 to 803 in c457c75 I also feel like when I revert the fix, the Windows test fail about different packages e.g. it complains about I don't think I'll be able to dig into this much further by myself I'm afraid as I've not found any solid difference between Windows and Linux 😞 |
|
@wraithgar I've got the tests passing in a manner that you might not be too impressed by, but that I think at least shows the issue isn't with my change |
|
The workaround is very intentional and well commented. It's always these one-line tweaks that get so far off the rails when it comes to testing. Thank you for seeing this through. |
|
It's possible the mock npm fixture has a quirk in windows with this caching but fixing that is way outside the scope of this PR. |
|
Is there a chance of this getting backported? |
|
@lkraav we typically don't actively do backports but this would probably be something we would consider if a PR was made against the v10 branch |
|
I have opened #8449 backporting this, unfortunately CI for Linux and macOS is failing - since (ironically) Windows is passing, I'm guessing it's cache related and I wasn't able to figure out the root cause for this PR. My very hacky work for exploring this is in https://github.com/G-Rath/cli/tree/prune-optional-peer2 if someone wants to have a crack at digging further - I'm not sure if I'll have the time this week |
|
Yeah, this change should be reverted or revisited. We tried upgrading our repos to npm 11.5.x, and this broke |
|
A potential forward fix is hinted at by this comment, as well as #8489:
I.e. it sounds like the ideal tree is incorrect, and so these deps end up getting pruned. If we can fix the ideal tree, then this PR may not actually be problematic. |
|
I think there is still some bug that causes unstable lockfile content for optional peer dependencies. I don't think it's related to platform-specific dependencies, seen it with any kind of optional peer dependencies. |
Your workaround didn't work for me running tests locally. I avoided network by adding the dep to fixture |
|
@G-Rath my current leaning is to revert this change. I think it is correct, and a good change, but the side effects of other bugs have made this a pretty wide-reaching breaking change for folks. Since the flag fixes are pretty deep internals, I'm not confident we can get a fix for how peer/optional flags flow through the system working correctly quickly. I know that would be disappointing - do you have thoughts about that or alternatives? |
|
@owlstronaut if you think that's best, then go for it - frankly, not meaning to be rude but what would be most disappointing about that is I don't expect it'll get prioritized anytime soon given the original issue (like some of my others) was open for 2+ years with seemingly next to no maintainer discussion or indication that it had been considered for trying to address 🙃 I would be interested in knowing if you're saying this primarily because of the feedback in this repo or if you've also received other feedback elsewhere (such as from enterprise folks). |
- reverts pruning added in #8431, which incorrectly prunes deps flagged as `peer` and `optional` - these flags don't mean that this node is an optional peer! - reverts much of #8579, which I think mistakenly changed peer dep calculation logic - rewrites calcDepFlags - adds logic to avoid unsetting `extraneous` when following optional peer edges (how #8431, should have been fixed) - updates my prev fix to avoid looking for missing optional peer deps (`if ((!edge.to && edge.type !== 'peerOptional') || !edge.valid) {`) - refactors dep flag unsetting and resetting into Node methods - removes `shake out Link target timing issue` test, which was testing code [removed](2db6c08#diff-6778dbd4bbfddaeb827a8d2aa7248d4c9b329229f69e407d5fd487abe16dd942L333) a while back - avoids omitting flaky`selflink` fixture when writing snapshots Fixes #8535
… breaking change in npm 11.5.0 in how it handles optional peer dependencies. See the discussion in npm/cli#8431 for more details.
This PR: - Adds an ignore rule to cspell for GHSA IDs. - Bumps node to v24 for the repo (which is bundled with npm v11), updating the lint CircleCI jobs and release GitHub action as well. - This is because npm trusted publishing requires at least npm v11.5.1. - Stops passing `NPM_TOKEN` to `changesets/action` in the release GitHub action. - Note that npm versions that support trusted publishing will [ignore locally configured tokens when OIDC environment variables are present](https://github.com/npm/cli/blob/8afa3bd21461c0984caf1bcc2e486c4881bda516/lib/utils/oidc.js#L141) (which they are for GH actions, since we've set that up), so `NPM_TOKEN` would be ignored anyway. But the main reason for this change is to stop `changesets/action` from printing a misleading log message saying `NPM_TOKEN` has been placed into `.npmrc` (which, while true, will be ignored by `npm publish`). - Note that we still need to keep the `NPM_TOKEN` GitHub secret around to run any tag-changing scripts, as `npm dist-tag` sadly doesn't support OIDC yet (see npm/cli#8547 for discussion). This means we'll need to manually rotate the token every 90 days. - Pins the transitive dev dependency `@inquirer/external-editor` to `1.0.0`. - The gist is that npm v11.5.0 introduced a breaking change in how unused optional peer dependencies are handed with npm/cli#8431 (see the discussion there for details). Specifically, the change causes those dependencies to be removed from `package-lock.json`, and this will cause `npm ci` in earlier versions of npm to error, complaining about `package-lock.json` being out of sync with `package.json`. `@inquirer/external-editor` introduced such an optional peer dependency in `1.0.1`, and the simplest fix here is to just fallback to `1.0.0`. - Uses `npm ci` instead of `npm i` in the release GitHub action. - As a requirement for releasing (or filing a release PR), the `package-lock.json` should be aligned with the `package.json`. - Stops setting `FEDERATION_VERSION` in the release GitHub action since it's no longer used. - Sets the tag for npm publishes to the branch name for `version-*` branches. - Previously, it was the default of `latest`, which was causing backport releases to mistakenly change the `latest` tag (used when someone `npm i`s without a version number). - We also tightened the `version-*` branch pattern down to `version-[0-9]+.[0-9]+` (since it's getting passed around in bash now).
…lique allowScripts Depuis que Dependabot a régénéré package-lock.json avec npm 11 (#118, #119), npm ci échoue avec npm 10 (Node 22) et avec npm 11 avant 11.5.0 : EUSAGE, « Missing: chokidar@5.0.0 / readdirp@5.1.1 from lock file ». npm 11.5.0 ne garde plus dans le lock les dépendances peer optionnelles que rien ne demande (npm/cli#8431). Or engines n'acceptait que Node 22, 24 et 26, quel que soit leur npm. - engines.npm >=11.18.0 : avec engine-strict, un npm plus ancien refuse l'installation (EBADENGINE), en donnant la version exigée. 11.5.0 suffit pour lire le lock, mais npm ignore strict-allow-scripts (#123) avant 11.16.0, et 11.16 et 11.17 rejettent fsevents (optionnel, macOS seulement) même là où il n'est pas installé (npm/cli#9602). - engines.node ne change pas : Node 22 (npm 10), Node 24 avant 24.20 et Node 26 avant 26.6 passent avec un npm 11 récent installé à part. - Le lock recopie engines. - CLAUDE.md dit pourquoi npm 11.18.0 est requis. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>




Currently optional peer dependencies are retained so long as at least one package in the tree has them as an optional peer dependency, meaning once added they become non-optional even though
npmdoes actually seem to mark such dependencies.To resolve this, I've modified the pruning logic to check for nodes that are both
optionalandpeer, in addition toextraneousnodes.References
Resolves #4737