Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RRFC] Use peerDependencies for some lit dependencies #31

Open
1 task done
augustjk opened this issue Oct 25, 2023 · 0 comments
Open
1 task done

[RRFC] Use peerDependencies for some lit dependencies #31

augustjk opened this issue Oct 25, 2023 · 0 comments

Comments

@augustjk
Copy link
Member

augustjk commented Oct 25, 2023

  • I searched for an existing RRFC which might be relevant to my RRFC

Motivation

We've been getting reports of users having multiple versions of Lit packages being loaded due to package managers failing to dedupe core lit packages.
While our version constraints are such that it should be fine to have multiple versions of Lit within the designated sem ver loaded for an application, it is suboptimal to do so as it means shipping more code than necessary to the client.

Marking as peerDependency might signal to package managers that it should be sharing the package rather than creating a nested dependency.

I'm opening this as an RRFC because I don't know if package mangers like npm, pnpm, or yarn actually behave in this way, nor am sure of any potential downsides like getting hard npm install errors due to having conflicting peer dependencies.

Current Behavior

Depending on other installed packages that depend on lit and which version was installed first, we can end up with multiple copies of a package nested like:

node_modules/lit/node_modules/@lit/reactive-element
node_modules/lit/node_modules/lit-element/node_modules/@lit/reactive-element
node_modules/@lit/reactive-element
node_modules/@lit-labs/virtualizer/node_modules/lit...

Desired Behavior

Proper hoisting of shared dependencies with compatible versions.

How

We need to consider which packages should be marked as peer dependency.

For example, @lit-labs/motion depends on lit because it directly imports from it classes, functions, and sentinel values. However, its exports are a directive and a reactive controller that are always meant to used in a project already using lit. Making lit a peer dependency here would signal that the version of lit being used by @lit-labs/motion should always come along side it, rather than be nested under it.

This line is more blurry when we consider @lit-labs/virtualizer which exports the virtualize directive meant to be used along side in a lit project, but also exports the lit-virtualizer component which can be used stand alone where the version of lit being used does not matter.[1]

The situation with the core packages of lit, lit-element, and @lit/reactive-element is also open to debate. Currently lit depends on @lit/reactive-element as well as lit-element which itself depends on @lit/reactive-element, potentially leading to:

node_modules/lit/node_modules/@lit/reactive-element
node_modules/lit/node_modules/lit-element/node_modules/@lit/reactive-element

It could be possible that if @lit/reactive-element is a peer dependency of lit-element, npm would never nest @lit/reactive-element under lit-element and look for it as a sibling, or a parent in the package tree. This would at least ensure that we don't get multiple versions of @lit/reactive-element within a single lit package installation. This is conjecture based on npm docs on peer dependencies[2] and needs to be verified.

Peer dependencies that are not explicitly marked as optional are auto installed as of npm 7[3] so an argument can be made for marking lit's dependency on lit-element and @lit/reactive-element as peer to really promote hoisting, though this could increase the blast radius of causing conflicts.

Other considerations

Package managers should also be able to dedupe and hoist dependencies that satisfy semver across multiple packages so it shouldn't matter whether something is marked as a dependency or a peer dependency in that sense.

Having multiple versions of Lit is technically fine and not detrimental to most users. If users want to optimize, it is possible to manually tweak the installed dependencies, coerce package managers to hoist or dedupe by blowing away node_modules and the lockfile, or use npm overrides/yarn resolutions to force a single version.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant