Recompiling npm packages and modern-browsers package

In the process of upgrading a production Meteor 2.7.2 app to 2.16 (and eventually 3.0), we started updating all its npm packages. We ran into the issue of the npm @tsparticles/confetti package using modern syntax like async/await, ?? (nullish coalescing operator) and object?.key (optional chaining).

This all works fine in the current versions of Chrome, Firefox, Edge, and Safari, but our app gets loaded on a lot of older smart TV browsers which use, in one example, LG webOS TV. Its latest native browser is built on Chromium 68.

Upon downloading Chromium 68 and testing, we can indeed see the browser crashing on the ?? operator in the above npm module.

We added the following to the package.js file per Meteor’s Recompiling npm packages doc.

"meteor": {
   ...
   "nodeModules": {
      "recompile": {
          "@tsparticles/confetti": ["web"]
          ...
      }
   }
}

The good news is it works (which is nice since it was broken in 2.7.2 and we had to use an older version of this package until we updated Meteor).

My question is this - there’s several options to pass to the npm package to recompile. There’s legacy, web, client, server, etc.

The only way I could get the recompilation to work in Chromium 68 was to pass web. However, upon digging around the source code in module.js in the browser, passing web causes every browser to get the recompilation, including the current version of the modern ones. Only passing legacy didn’t fix any of the browsers and Chromium 68 still broke.

As ideally, I only want the recompilation to be for legacy browsers and not for the modern ones. Is there some kind of update I need to make in a call to the modern-browsers package or something?

In the modern-browsers package, it sets browser versions for classes, generator functions, template literals, and symbols.

I’m thinking maybe the legacy version of Chrome is way off for symbols as it’s currently set to 38 and I’m seeing that Chromium 68 doesn’t handle the symbols mentioned above. If I understand correctly, only Chrome 38 and below would receive the legacy build relating to symbols?

Anyone have any experience here or can shed any light on the matter?

1 Like

Upon a bit more tinkering and re-reading the article Meteor 1.7 and the evergreen dream, the last part that’s passed to setMinimumBrowserVersions is just a string label for why these versions are set.

I added the following to my startup/server/configurations.js file:

import { setMinimumBrowserVersions } from "meteor/modern-browsers";

setMinimumBrowserVersions({
  chrome: 69,
}, "For @tsparticles/confetti npm package");

And then updated my package.js recompilation to use legacy only and BAM… it worked. Chromium 68 works and gets the recompiled version and modern Chrome gets the version with async/await, ??, and object?.key. You can call setMinimumBrowserVersions as many times as you want and the highest version of each browser is the one used by the compiler.

And I can even adjust the 69 down to 68 or 67 and see it break immediately. Also, it occurred to me this one “case” I found is for Chromium 68 but that the ?? nullish coalescing operator likely doesn’t work in later browser versions as well. I checked on MDN and sure enough ?? needs at least Chrome 80 along with several other later browser versions. So I’ll be updating my setMinimumBrowserVersion call with those.

BTW, I love that there’s seemingly no documentation from Meteor on the modern-browsers function setMinimumBrowserVersion. I had to glean it from an old blog post regarding Meteor 1.7. I think I’ll open a ticket just for the documentation.

3 Likes

It would be nice to update the documentation with this info. Also probably good idea to have another PR that would update the default settings to account for new abilities.

1 Like