yarnpkg / berry

📦🐈 Active development trunk for Yarn ⚒
https://yarnpkg.com
BSD 2-Clause "Simplified" License
7.38k stars 1.11k forks source link

[Feature] Support upstreaming / telemetry on packageExtensions #3585

Open crubier opened 2 years ago

crubier commented 2 years ago

Describe the user story

As a developer, I often want to just install packages, but very often (too often), package creators do not fill their peer dependencies correctly. This invariably leads to huge .yarnrc.yml where we have to add peer dependencies to packages to avoid yarn YN0002 warnings.

Typical .yarnrc/yml:

packageExtensions:
  "@chakra-ui/accordion@1.3.6":
    peerDependencies:
      framer-motion: "*"
  "@chakra-ui/anatomy@1.0.0":
    peerDependencies:
      "@chakra-ui/system": "*"
  "@chakra-ui/skeleton@1.1.18":
    peerDependencies:
      "@chakra-ui/theme": "*"
      "@emotion/react": "*"
      "@emotion/styled": "*"
  "@chakra-ui/switch@1.2.9":
    peerDependencies:
      framer-motion: "*"
  "@endemolshinegroup/cosmiconfig-typescript-loader@3.0.2":
    peerDependencies:
      typescript: "*"
  "@graphql-codegen/cli@1.21.4":
    peerDependencies:
      typescript: "*"
  "@storybook/core-server@*":
    peerDependencies:
      "@babel/core": "*"
  "@storybook/core@*":
    peerDependencies:
      "@babel/core": "*"
      webpack: "*"
  "@storybook/store@*":
    peerDependencies:
      "react": "*"
      "react-dom": "*"
  "@storybook/csf-tools@*":
    peerDependencies:
      "@babel/core": "*"
  "@parcel/packager-html@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/plugin@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/packager-svg@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/types@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/bundler-default@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/compressor-raw@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/namer-default@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/optimizer-cssnano@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/optimizer-htmlnano@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/optimizer-image@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/optimizer-svgo@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/optimizer-terser@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/packager-css@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/packager-js@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/packager-raw@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/reporter-dev-server@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/resolver-default@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/runtime-browser-hmr@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/runtime-js@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/runtime-react-refresh@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/runtime-service-worker@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-babel@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-css@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-html@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-image@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-js@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-json@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-postcss@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-posthtml@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-raw@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-react-refresh-wrap@*":
    peerDependencies:
      "@parcel/core": "*"
  "@parcel/transformer-svg@*":
    peerDependencies:
      "@parcel/core": "*"
  eslint-config-airbnb-typescript@12.3.1:
    peerDependencies:
      eslint: "*"
      eslint-plugin-import: "*"
      eslint-plugin-jsx-a11y: "*"
      eslint-plugin-react: "*"
      eslint-plugin-react-hooks: "*"
  graphql-config@*:
    peerDependencies:
      typescript: "*"
  apollo-server-micro@*:
    peerDependencies:
      graphql: "*"
  next@*:
    peerDependencies:
      "@babel/core": "*"
  react-dev-utils@11.0.4:
    peerDependencies:
      typescript: "*"
      webpack: "*"
  styled-jsx@*:
    peerDependencies:
      "@babel/core": "*"
  next-auth@*:
    peerDependencies:
      "@prisma/client": "*"

Describe the solution you'd like

Maybe there could be a way for yarn to add some telemetry to this part of the code, and have a central source of truth, to let package creators know about their bad peerDeps ?

Opening issues automatically on repos sounds a bit difficult, but just have a central place to report it at least would be helpful ?

Describe the drawbacks of your solution

Need to maintain this solution.

Describe alternatives you've considered

I stopped bothering enough to open issues every time I have issues with peerDeps in packages I use.

arcanis commented 2 years ago

It already exists! https://github.com/yarnpkg/berry/blob/master/packages/plugin-compat/sources/extensions.ts

crubier commented 2 years ago

Hmm interesting !

But if I find issues with packages on my side, I still have to edit https://github.com/yarnpkg/berry/blob/master/packages/plugin-compat/sources/extensions.ts (and create the associated issues) manually, right ?

The idea I had here was about basically filling something like this file, but automatically.

This seems automatable, since solving the YN0002 warning is trivial, since the error message contains all necessary information.

crubier commented 2 years ago

Basically a workflow like:

  1. ANY yarn install raises a YN0002 warning for any user in the world
  2. The appropriate lines get added to their local .yarnrc.yml automatically (maybe with a CLI flag or something)
  3. A PR is automatically created on https://github.com/yarnpkg/berry/blob/master/packages/plugin-compat/sources/extensions.ts , with the appropriate lines
crubier commented 2 years ago

I guess I would call it @yarn/plugin-auto-compat, it would use octokit.js to create a PR maybe

arcanis commented 2 years ago

I think @missing1984 mentioned yesterday he wrote a tool to catch and autofix such issues locally 🤔

Some problems with completely automated approaches:

missing1984 commented 2 years ago

not autofix unfortunately.. I built a plugin that automatically load the extension from a global place within our company. it still need people involve to figure out the right overrides.. i've think of automate that but given the nature of the problem it will never be 100% correct especially for the regular and peer dependency thing you mentioned.