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

Add fully supports and partially supports queries #787

Merged
merged 4 commits into from Sep 26, 2023

Conversation

BPScott
Copy link
Contributor

@BPScott BPScott commented Sep 3, 2023

Context

Caniuse features can be marked as "fully supported", "partially supported" and a few other values that aren't relevant to this reminder/primer (see the stats key in caniuse docs). For instance for the es6 feature, partial support began with Chrome 21 but wasn't marked as fully supported till Chrome 51.

Browserslist's supports query includes browsers with both full and partial support for a given feature. Thus supports es6 includes Chrome 21 and up. This is somewhat surprising to me as if you'd try to use es6 features in Chrome 21 things would go very wrong very quickly. I hope to think of browserslist's supports query as "this is a baseline from which you can assume full support for a feature, so stuff like babel won't need to transpile/polyfill this at all", but thanks to it's partial support that's not quite what it does.

I'd like a way to make a supports query that only considers full support, instead of partial and full support. I appreciate that changing the behaviour of supports after so long would be an unexpected change to the point of it being a breaking change and so a new query would be needed.

This PR is an approach to solve that problem, but I'd love some feedback on naming.

This PR

This PR adds a fully supports query, that acts like supports except it only considers full browser support. As a result fully supports es6's first Chrome version is Chrome 51.

I'm not super tied to the fully supports name and it feels a bit clunky. In an ideal world it'd feel nicer for supports to be for full support, and then we have a modifier if we want to include partial support, but I know that's almost certainly too disruptive to ship. I would welcome suggestions for any syntax that you'd prefer.

One alternative is having supports es6 fully - where fully is a modifier of the existing supports query, kinda like how you can do >5% and >5% in US.

Another alternative is betting on this prefix more, and adding partially supports as a query too (with the same behaviour as supports currently and pushing people to use fully supports and partially supports instead of supports. This kinda leans into the magical future world where we could change the default behaviour of supports to be "full support", and then people have to opt in if they want to include partial support.

This is like the `supports` query, except it does not include browsers
with partial support for the given feature.
@Semigradsky
Copy link
Contributor

In an ideal world it'd feel nicer for supports to be for full support, and then we have a modifier if we want to include partial support,

👍
From readme:

supports es6-module: browsers with support for specific features

It doesn't look like "partial" support. Is current behaviour bug?

@ai
Copy link
Member

ai commented Sep 3, 2023

Can you show popular real-world example when this query will be useful?

@BPScott
Copy link
Contributor Author

BPScott commented Sep 9, 2023

Sorry for the slow reply, it's been a busy week.

It doesn't look like "partial" support. Is current behaviour bug?

It's debatable. If I were reviewing code when supports was added then I'd consider it a bug and that I'd expect supports to be for full support only. However the current behaviour of including partial support has been in browserslist for so long that it's almost became relied upon behaviour and I'd be nervous about changing it outside of a major version (and a major release is too disruptive without a really really good reason so that's not happening).

"Change the behaviour of supports to omit partial support and we don't need to add any new query" would also be an acceptable solution but I doubt @ai would consider that change not disruptive enough to include in a minor/patch version.

Can you show popular real-world example when this query will be useful?

I'm not sure I can ensure "popular", as partial support in caniuse's syntax is relatively rare these days - it was more prevalent when browsers introduced features with vendor prefixes rather than behind feature flags.

Recent features that make heavy use of partial supports are container queries, container style queries,

supports es6-module is probably the most common supports query, and is mentioned on https://browsersl.ist. The support for es6-module is mostly full however Safari 10.1 and iOS 10.3 are marked as having partial support due to them lacking support for the nomodule syntax. I think it is surprising that supports es6-module would include those two browsers.

If users wished to use nomodule as a way of doing differential serving - sending legacy js to older browsers and a build targeting supports es6-module to newer browsers with: <script nomodule src="/dist/index.legacy.js"></script> <script type="module" src="/dist/index.esm.js"></script> users would find that their esm build would contain transforms and polyfills for Safari 10.1 and iOS 10.3 even through this code would never be served to those browsers thanks to the lack of nomodule support.

Currently defaults and supports es6 would include KaiOS 2.5, which only has partial es6 support which seems feels unexpected at first glance.

My particular use-case is for creating builds for long-tail legacy browsers, I'd want to use fully supports es6 as a mechanism to select all browsers with es6 support, supports es6 contains a multitude of browsers that have partial support for es6 and using it as a target would result in the inclusion of several undesired transforms and polyfills.

@ai
Copy link
Member

ai commented Sep 10, 2023

Yes, these use cases look legit. I will think about adding it.

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
@BPScott
Copy link
Contributor Author

BPScott commented Sep 24, 2023

I've pushed up a new commit, to try to improve the documentation by adding an example referencing css-grid (which is a mentioned example query on https://browsersl.ist/.

When thinking about documentation and how to teach this I felt that the difference between supports and fully supports wasn't super obvious.

So try to solve this I've added a partially supports query that acts the same as supports. The documentation describes the difference between fully supports and partially supports, and then notes that supports is an alias for partially supports. In the future, Browserslist v5 could remove supports or make it be an alias for fully supports.


I've moved the existing examples of supports queries to use partially supports. I'm tempted to say these should be fully supports, @ai do you have a preference?

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
@ai
Copy link
Member

ai commented Sep 24, 2023

I'm tempted to say these should be fully supports, @ai do you have a preference?

Let’s move to fully in examples

@BPScott BPScott changed the title Add fully supports query Add fully supports and partially supports queries Sep 24, 2023
`partially supports` does the same thing as `supports` but makes it
clearer that it includes partial browser support.

It feels easier to teach the difference between `fully supports` and
`partially supports` and then say `supports` is an alias` of
`partially supports`.
@BPScott
Copy link
Contributor Author

BPScott commented Sep 24, 2023

I think I've addressed everything. Website update PR is at browserslist/browsersl.ist#522. Let me know when you're you've got no more feedback, and I can squash these commits down prior to merge.


@ai one last question: I made this PR working on the assumption that changing the current behaviour of supports to only look for fully supported browsers would not be a desirable change. Do you feel that's the correct call? If you feel that would be acceptable I'd happily replace this PR with a much simpler one that changes that logic:

function isSupported(flags) {
-  return (
-    typeof flags === 'string' &&
-    (flags.indexOf('y') >= 0 || flags.indexOf('a') >= 0)
-  )
+ return typeof flags === 'string' && flags.indexOf('y') >= 0;
}

@ai ai merged commit 686cc18 into browserslist:main Sep 26, 2023
7 checks passed
@ai
Copy link
Member

ai commented Sep 26, 2023

Thanks. Released in 4.22.

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

Successfully merging this pull request may close these issues.

None yet

4 participants