Client Architecture / clientArch / web.browser.legacy

I’ve noticed lately in Monti ( but I guess people using other Kadria variants see the same ) that a lot of modern browsers on one of our apps are using the web.browser.legacy architecture. Here’s a few examples of browsers I’ve seen get the legacy bundle.

Safari (WebKit) - 13.1.2 Mac OS - 10.15.4
Chrome - 85.0.4183.133 Chromium OS - 13310.93.0
Mobile Safari (WebKit) - 14.0 iOS - 14.0.1, mobile - Apple iPhone

But there are also examples of some getting the correct modern bundle. It seems a bit random?

In our other app much older versions of different browsers are getting the modern (web.browser) bundle as you’d expect.
Chrome - 85.0.4183.133 Chromium OS - 13310.93.0

Both apps are on Meteor 1.11 and whilst there are differences they use a pretty similar set of packages.

Has anyone had any experience with this? Any ideas for debugging it?

The modern-browsers package decides if the legacy or modern architecture should be used. When the server starts, packages or the app call setMinimumBrowserVersions to configure the minimum browser versions that support the modern architecture. There doesn’t seem to be an API to access the minimum versions, but you could start Meteor with meteor --inspect and create a breakpoint in the modern-browsers package to check what it is set to in each app.

I’ve noticed lately in Monti ( but I guess people using other Kadria variants see the same ) that a lot of modern browsers on one of our apps are using the web.browser.legacy architecture.

This feature is unique to Monti APM. I’m excited that it was useful for you.

1 Like

This feature is unique to Monti APM. I’m excited that it was useful for you.

Oh right, didn’t realise. Another nice feature you added :clap:

I’ll try what you say and fingers crossed some obvious culprit crops up. Thanks for the tips :+1:

Hi @zodern,

I would like to know how to see it in Monti.

I’m wondering if our Cordova (both iOS and Android) are using modern browser or legacy. We’re using the paid version of Monti. I just don’t have any idea where to look for it.

Thanks.

Cordova is a separate architecture, but it is considered legacy and mostly includes the same code and is compiled in the same way as the legacy web arch. How the modern and legacy architectures are designed is legacy is the default architecture since it should work almost anywhere, and the modern arch is considered an optional optimization for when Meteor knows the client supports it. With that design, the legacy arch worked better for cordova.

Monti APM shows the architecture for client errors, which I assume @marklynch was referring to. We’re working on a new feature to monitor the client, which will show how many users use each architecture, and which browsers are using the legacy arch.

1 Like

@zodern , thanks for the detailed explanation. Not what I hoped but very interesting indeed.

We’re trying to debug Google Maps JS API on Cordova. Their latests release have implemented ES2020 natively and they stopped working on Cordova (both Android and iOS) even with recent webviews that should, from our understanding, support ES2020.

So we had the hypothetis it was because Cordova was using legacy

The discussion is here: Using Google maps js api with Cordova

Thanks for your help and thanks for always improving Monti! We love it.

Burni

Anybody knows how to force Cordova to use Modern bundle ?

It seems to be the problem for us that Cordova’s bundle does not support loading the new Google Maps JS API that is now based on ES2020.

It’s discussed in the last posts of this thread here:

Best regards,

Burni

We have done one very interesting test in Cordova through Chrome Inspector (idea of @receptim), we ran our app using :
1-The standard localhost:12924 port (so using the bundle made for Cordova)
2-Through an external URL that connects to the Node server directly

We see clearly that both:
1-Can run ES2020 functions
2-Have exactly the same Array.from (it was a possible cause for our Google Maps problems)

However, their “Map” object is different and that messes up with Google Maps JS API.

Here, see the test:

let oda=new Map([[1,["msie"]],[2,["edge"]],[3,["chrome","crios"]],[5,["firefox","fxios"]],[4,["applewebkit"]],[6,["trident"]],[7,["mozilla"]]]);

for(const [d,e]of aoda.entries()){ console.log('d='+d +' e='+e)}

In Localhost:12490, it fails with the same error as Google Maps’s JS API

image.png

While on modern bundle, it works just fine:

image.png

Why is that object different?
How can we put it back like it is in a modern browser bundle ?

Any idea what to do ?

Regartds,

Burni

This part of Meteor hasn’t really been maintained in years, when it really needs yearly updates. Right now most browsers can use the modern bundle without problem. However, if Meteor starts maintaining it and follows the original plan, the modern bundle might not support all browser versions cordova could use. The other issue is that Meteor has no idea at build time what the browser support for the modern client is - that information is only available to server code at runtime and can be changed by any app or package.

I was hoping Meteor 3 would drop support for browsers that do not have native es6 classes. That would fix most issues with the legacy/cordova clients since it would allow removing many of the babel plugins and polyfills used for the legacy client. It might fix this issue with Google maps since it would allow using the native Map object.

The other solution would be to update ecmascript-runtime-client with polyfills that follow newer ECMAScript specs.

I had written a post on how to update this part of Meteor is anyone wants to - Discussion on Update ECMAScript 2015 to 2023 - #3 by zodern

Thanks a lot @zodern for pointing us in this direction!!

so far, we’ve tried to
1-comment out these lines in ecmascript-runtime-client/web.cordova/legacy.js :

2-or try to use the content of modern.js in legacy.js

both do fail to load the app:

It seems the code somewhere else depend on those “overrides”.

So what we’re probably going to try is before these lines are run, copy the Map.prototype in another object and override it again after those lines.

It seems sketchy but it’s probably an interesting test to do.
Have you tried it already ?

Regards,

burni13

The ecmascript-runtime-client exports Map, Set, and Symbol in the legacy client, so other packages that use ecmascript use those exports instead of the globals. If you are removing the exports, you also need to remove the exports from its package.js file.

Another option might be to update the version of core-js used in the package. There’s some bug fixes related to this in newer versions. If that doesn’t fix it, there might be an issue with Meteor missing an import from core-js.

@zodern

thanks a lot!

So far, we’ve managed to comment-out the 3 overrides that seem problematic in ecmascript-runtime-client/web.cordova/legacy.js :

try {
  console.log("ligne1");
//  Symbol = exports.Symbol = require("core-js/es/symbol");
//  Map = exports.Map = require("core-js/full/map");
//  Set = exports.Set = require("core-js/es/set");


} catch (e) {
  throw new Error([
    "The core-js npm package could not be found in your node_modules ",
    "directory. Please run the following command to install it:",
    "",
    "  meteor npm install --save core-js",
    ""
  ].join("\n"));
}

This does work when run locally and from laptop but so far it seems to break a HCP.

And last but not least, it does allow Google maps to work out of the box on all iOS 15+ (so it works with iPhone 6 from 2015-2016) and Android versions (as long as Chrome has been updated to a recent version, since its used as a webview)

Stay tuned!