You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 peerDependencymight 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:
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:
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.
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: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 onlit
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 usinglit
. Makinglit
a peer dependency here would signal that the version oflit
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 thevirtualize
directive meant to be used along side in alit
project, but also exports thelit-virtualizer
component which can be used stand alone where the version oflit
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. Currentlylit
depends on@lit/reactive-element
as well aslit-element
which itself depends on@lit/reactive-element
, potentially leading to:It could be possible that if
@lit/reactive-element
is a peer dependency oflit-element
, npm would never nest@lit/reactive-element
underlit-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 singlelit
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 onlit-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
The text was updated successfully, but these errors were encountered: