browserslist / browserslist

🦔 Share target browsers between different front-end tools, like Autoprefixer, Stylelint and babel-preset-env

Home Page:https://browsersl.ist

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Opera mobile is invalid with mobileToDesktop

steverep opened this issue · comments

Unlike Android, Chrome, and Firefox, Opera's mobile version history does not mirror that of Opera desktop. With the mobileToDesktop option enabled, the results are invalid:

$ ./cli.js --mobile-to-desktop  "last 2 op_mob versions"
op_mob 98
op_mob 97

Those versions don't exist - the latest is 75. Furthermore, time queries or feature queries (after fixing #761) for this latest version will then use data for Opera desktop 75, which is much older and based on Chromium 89 versus 112.

I would propose removing it from the mobile to desktop mapping unless the versions can be properly mapped in terms of release date and/or chromium version.

A filter similar to the one used for Android is also needed to stop "last_version" queries from grabbing very old versions without mobileToDesktop:

$ ./cli.js  "last 2 op_mob versions"
op_mob 73
op_mob 12.1

Removing it will be breaking change 😔

You need to ask Babel team at least

Based on the updated information provided regarding issue #761, perhaps handling mobile-to-desktop mapping using an alternative approach that takes into account release dates and provides consistent results across platforms:

// Define the mapping of mobile versions to their corresponding desktop versions
const mobileToDesktopMap = {
  'op_mob 98': 'opera 80',
  'op_mob 97': 'opera 79',
  // Add more mappings as needed
};

// Function to retrieve the corresponding desktop version based on the given mobile version
function getDesktopVersion(mobileVersion) {
  // Check if the mobile version exists in the mapping
  if (mobileVersion in mobileToDesktopMap) {
    return mobileToDesktopMap[mobileVersion];
  }
  
  // If no mapping is found, return the original mobile version
  return mobileVersion;
}

// Example usage
const mobileVersion = 'op_mob 98';
const desktopVersion = getDesktopVersion(mobileVersion);
console.log(desktopVersion); // Output: opera 80

In this example, we define a mobileToDesktopMap object that maps mobile versions to their corresponding desktop versions. The getDesktopVersion() function takes a mobile version as input and checks if there is a mapping available in the mobileToDesktopMap. If a mapping is found, it returns the corresponding desktop version; otherwise, it returns the original mobile version.

One can incorporate this mapping mechanism where mobile-to-desktop mapping is required, such as when processing queries or generating results based on different platforms. By using this approach, one can ensure consistent and accurate mappings between mobile and desktop versions, regardless of the presence of feature queries or other factors.

This code example is a simplified demonstration and should be adapted and expanded to fit your specific requirements and code structure.

Can you cc the right contact then? From the debug output of preset-env, it appears they don't even use it with the exception of Android:

Babel config for browserslist query of "since 1990"

@babel/preset-env: DEBUG option

Using targets:
{
"android": "2.1",
"chrome": "4",
"edge": "12",
"firefox": "2",
"ie": "5.5",
"ios": "3.2",
"opera": "9",
"safari": "3.1",
"samsung": "4"
}

Using modules transform: auto

Using plugins:
proposal-class-static-block { android, chrome < 94, edge < 94, firefox < 93, ie, ios, opera < 80, safari, samsung < 17 }
proposal-private-property-in-object { android, chrome < 91, edge < 91, firefox < 90, ie, ios < 15, opera < 77, safari < 15, samsung < 16 }
proposal-class-properties { android, chrome < 74, edge < 79, firefox < 90, ie, ios < 15, opera < 62, safari < 14.1, samsung < 11 }
proposal-private-methods { android, chrome < 84, edge < 84, firefox < 90, ie, ios < 15, opera < 70, safari < 15, samsung < 14 }
proposal-numeric-separator { android, chrome < 75, edge < 79, firefox < 70, ie, ios < 13, opera < 62, safari < 13, samsung < 11 }
proposal-logical-assignment-operators { android, chrome < 85, edge < 85, firefox < 79, ie, ios < 14, opera < 71, safari < 14, samsung < 14 }
proposal-nullish-coalescing-operator { android, chrome < 80, edge < 80, firefox < 72, ie, ios < 13.4, opera < 67, safari < 13.1, samsung < 13 }
proposal-optional-chaining { android, chrome < 80, edge < 80, firefox < 74, ie, ios < 13.4, opera < 67, safari < 13.1, samsung < 13 }
proposal-json-strings { android, chrome < 66, edge < 79, firefox < 62, ie, ios < 12, opera < 53, safari < 12, samsung < 9 }
proposal-optional-catch-binding { android, chrome < 66, edge < 79, firefox < 58, ie, ios < 11.3, opera < 53, safari < 11.1, samsung < 9 }
transform-parameters { android, chrome < 49, edge < 15, firefox < 53, ie, ios < 10, opera < 36, safari < 10, samsung < 5 }
proposal-async-generator-functions { android, chrome < 63, edge < 79, firefox < 57, ie, ios < 12, opera < 50, safari < 12, samsung < 8 }
proposal-object-rest-spread { android, chrome < 60, edge < 79, firefox < 55, ie, ios < 11.3, opera < 47, safari < 11.1, samsung < 8 }
transform-dotall-regex { android, chrome < 62, edge < 79, firefox < 78, ie, ios < 11.3, opera < 49, safari < 11.1, samsung < 8 }
proposal-unicode-property-regex { android, chrome < 64, edge < 79, firefox < 78, ie, ios < 11.3, opera < 51, safari < 11.1, samsung < 9 }
transform-named-capturing-groups-regex { android, chrome < 64, edge < 79, firefox < 78, ie, ios < 11.3, opera < 51, safari < 11.1, samsung < 9 }
transform-async-to-generator { android, chrome < 55, edge < 15, firefox < 52, ie, ios < 10.3, opera < 42, safari < 10.1, samsung < 6 }
transform-exponentiation-operator { android, chrome < 52, edge < 14, firefox < 52, ie, ios < 10.3, opera < 39, safari < 10.1, samsung < 6 }
transform-template-literals { android, chrome < 41, edge < 13, firefox < 34, ie, ios < 9, opera < 28, safari < 9 }
transform-literals { android, chrome < 44, firefox < 53, ie, ios < 9, opera < 31, safari < 9 }
transform-function-name { android, chrome < 51, edge < 14, firefox < 53, ie, ios < 10, opera < 38, safari < 10, samsung < 5 }
transform-arrow-functions { android, chrome < 47, edge < 13, firefox < 43, ie, ios < 10, opera < 34, safari < 10, samsung < 5 }
transform-block-scoped-functions { android, chrome < 41, firefox < 46, ie < 11, ios < 10, opera < 28, safari < 10 }
transform-classes { android, chrome < 46, edge < 13, firefox < 45, ie, ios < 10, opera < 33, safari < 10, samsung < 5 }
transform-object-super { android, chrome < 46, edge < 13, firefox < 45, ie, ios < 10, opera < 33, safari < 10, samsung < 5 }
transform-shorthand-properties { android, chrome < 43, firefox < 33, ie, ios < 9, opera < 30, safari < 9 }
transform-duplicate-keys { android, chrome < 42, firefox < 34, ie, ios < 9, opera < 29, safari < 9 }
transform-computed-properties { android, chrome < 44, firefox < 34, ie, ios < 8, opera < 31, safari < 7.1 }
transform-for-of { android, chrome < 51, edge < 15, firefox < 53, ie, ios < 10, opera < 38, safari < 10, samsung < 5 }
transform-sticky-regex { android, chrome < 49, edge < 13, firefox < 3, ie, ios < 10, opera < 36, safari < 10, samsung < 5 }
transform-unicode-escapes { android, chrome < 44, firefox < 53, ie, ios < 9, opera < 31, safari < 9 }
transform-unicode-regex { android, chrome < 50, edge < 13, firefox < 46, ie, ios < 12, opera < 37, safari < 12, samsung < 5 }
transform-spread { android, chrome < 46, edge < 13, firefox < 45, ie, ios < 10, opera < 33, safari < 10, samsung < 5 }
transform-destructuring { android, chrome < 51, edge < 15, firefox < 53, ie, ios < 10, opera < 38, safari < 10, samsung < 5 }
transform-block-scoping { android, chrome < 49, edge < 14, firefox < 51, ie, ios < 10, opera < 36, safari < 10, samsung < 5 }
transform-typeof-symbol { android, chrome < 38, firefox < 36, ie, ios < 9, opera < 25, safari < 9 }
transform-new-target { android, chrome < 46, edge < 14, firefox < 41, ie, ios < 10, opera < 33, safari < 10, samsung < 5 }
transform-regenerator { android, chrome < 50, edge < 13, firefox < 53, ie, ios < 10, opera < 37, safari < 10, samsung < 5 }
transform-member-expression-literals { android < 4, chrome < 7, ie < 9, ios < 6, opera < 12, safari < 5.1 }
transform-property-literals { android < 4, chrome < 7, ie < 9, ios < 6, opera < 12, safari < 5.1 }
transform-reserved-words { android < 4.4, chrome < 13, ie < 9, ios < 6, opera < 10.50 }
proposal-export-namespace-from { android < 72, chrome < 72, edge < 79, firefox < 80, ie, ios, opera < 60, safari, samsung < 11.0 }
syntax-dynamic-import
syntax-export-namespace-from
syntax-top-level-await
syntax-import-meta

@nicolo-ribaudo do you need op_mob in mobileToDesktop

If the current mapping is wrong, removing it can't make things worse. I need to do some testing to see how it affects existing Babel installs.

The difference is that the following query:

last 2 versions, not ie, not ie_mob

would start returning op_mob 12.1 and op_mob 73 instead of op_mob 94 and op_mob 95. It wouldn't technically be a breaking change for Babel, but it would cause much more compilation.

Yes, returning op_mini 12.1 on last 2 versions will add a lot of unnecessary polyfills.

@steverep can we add some hack for it?

You need to know how many versions were released between 12.1 and the current one. This is the same problem as with Android beyond v4.4.3, except that's a lot easier since we know the version history just follows Chrome. Since Opera desktop doesn't do the same, you'd need to fallback to hard coding the starting point and just assume versions are always increments of 1.0.

We can hardcode the first Chromuim-based (>12) Opera Mini version from https://en.wikipedia.org/wiki/History_of_the_Opera_web_browser and do the math

Got a fix coming that removes it from mobileToDesktop and handles the version jumps like Android:

$ ./cli.js  "last 2 op_mob versions, last 2 android versions"
android 114
op_mob 73

$ ./cli.js  "last 60 op_mob versions, last 78 android versions"
android 114
android 4.4.3-4.4.4
op_mob 73
op_mob 12.1

If you want to include it back later, a good option would be to import the Opera mobile data from MDN. They have release dates and a mapping to the blink engine version for the whole history.

Or just get caniuse to include that data 😉

If you want to include it back later, a good option would be to import the Opera mobile data from MDN

I am thinking of moving to MDN, but there are two main problems:

  1. It will require a huge refactoring and ecosystem’s migration and Browserslist funding (or respect from community) is not enough. It will be something around a few months of everyday work.
  2. @mdn/browser-compat-data is 12 MB compare to 2 MB of caniuse-lite. It is downgrade (and with Autoprefixer/Browserslist scale even a small ecological downgrade of CO2 from CI platforms) and I am ready for it only for strong reason.

I just meant using that one JSON file for now. You'd just need a script to keep it synced. Of course that then requires regular releases which is why it'd be nice if caniuse did it.

I just meant using that one JSON file for now. You'd just need a script to keep it synced. Of course that then requires regular releases which is why it'd be nice if caniuse did it.

We already do some copying from MDN database to caniuse-lite but it is soo hacky, so I prefer to avoid it for non-critical use cases.

The idea of caniuse-lite is to have 100% similar data to caniuse-db.

@nicolo-ribaudo it seems that Babel is still causing more transpilation with this fix. It seems to also be making a false equivalency between Opera desktop and mobile.

For a typical "defaults" query, the following Opera versions are now correctly returned:

  • op_mob 73
  • opera 99
  • opera 98

But preset-env is setting the targets as:

@babel/preset-env: `DEBUG` option

Using targets:
{
  "android": "113",
  "chrome": "109",
  "edge": "112",
  "firefox": "102",
  "ios": "15.6",
  "opera": "73",
  "safari": "15.6",
  "samsung": "20"
}

It seems to pick out the lowest version of Opera or op_mob to use as the target, and then treat that as the desktop version in terms of feature support. This is not correct.