Hi all,
I’m stuck with a cross-browser issue where several ES features are missing or half-implemented on older iPhones (older Safari/iOS) and the Xiaomi/MIUI browser. I can’t make them take effect for third-party libs.
Symptoms/errors
From real devices (screens attached, text below):
Uncaught TypeError: Invalid attempt to iterate non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.
and
Uncaught TypeError: this.state.customRenderingMap.values is not a function
or its return value is not iterable
So this looks like a missing/buggy Symbol.iterator
/ Map iterators and also missing Object.values
.
Object.values
reports present, yet code inside libraries (FullCalendar, Slate) still crashes with the iterator error above.
Affected libraries/places
useSearchParams
from react-router v6 (I replaced it with my own code, and that part started working).- FullCalendar (errors around
.values()
/ iteration inside its state map). - Slate also misbehaves in older iOS.
What I’ve tried in Meteor (none of these fixed it)
- Importing
core-js
first in the app entry (client/main.tsx
)
// client/main.tsx (first lines)
import 'regenerator-runtime/runtime';
import 'core-js/features/object/values';
import 'core-js/features/array/from';
import 'core-js/features/symbol';
import 'core-js/features/symbol/iterator';
import 'core-js/features/map';
import 'core-js/features/set';
// then React/Meteor app imports...
- Adding
@babel/preset-env
with built-ins
.babelrc
(or package.json
→ "babel"
):
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "entry",
"corejs": 3,
"targets": ">0.5%, not dead"
}],
"@babel/preset-react",
"@babel/preset-typescript"
]
}
and ensured the core-js
“entry” imports are included as above.
- Local Meteor package to force earliest load
packages/app-polyfills/package.js
Package.describe({ name: 'app:polyfills', version: '0.0.1' });
Package.onUse(api => {
api.versionsFrom('3.0'); // matches my Meteor version
api.use('ecmascript');
// load as bare to run before module system
api.addFiles('client.js', 'client', { bare: true });
api.addFiles('server.js', 'server', { bare: true });
});
packages/app-polyfills/client.js
import 'react-app-polyfill/ie11';
import 'core-js/features/array/find';
import 'core-js/features/array/flat';
import 'core-js/features/array/flat-map';
import 'core-js/features/array/includes';
import 'core-js/features/object/from-entries';
import 'core-js/features/object/assign';
import 'core-js/features/object/set-prototype-of';
import 'core-js/features/string/replace-all';
import 'core-js/features/promise';
import 'core-js/features/map';
import 'es7-object-polyfill';
import 'es6-set/polyfill';
Object.values = Object.values
? Object.values
: o => Object.keys(o).map(k => o[k]);
Number.isInteger =
Number.isInteger ||
(value => {
return (
typeof value === 'number' &&
isFinite(value) &&
Math.floor(value) === value
);
});
(then I tried both referencing UMD bundles and also switching to <script>
in head, see #4)
Added app:polyfills
at the top of .meteor/packages
.
- Hard-loading polyfills from a CDN before Meteor’s bundle (in
<head>
)
client/main.html
:
<head>
<script>
window.__EARLY__ = true;
</script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es.array.flat,es.array.from,es.object.assign,es.promise,globalThis,URL,URLSearchParams,fetch,TextEncoder,TextDecoder,AbortController,ReadableStream&flags=gated,always"></script>
</head>
What’s confusing
- Feature checks often return true after the above (e.g.
typeof Object.values === 'function'
,Symbol.iterator
exists), but libraries still throw “Invalid attempt to iterate non-iterable … must have a [Symbol.iterator]” during runtime. - This makes me suspect module/bundle evaluation order, or iterators being non-iterable (Safari-style) unless properly polyfilled/overridden, or Babel’s
for..of
helpers conflicting with half-native iterators.
Questions
- Is there a known working recipe for making iterator/Map/
Object.values
polyfills stick for third-party deps in Meteor (React app) on older iOS & MIUI browser? - Any Meteor-specific gotchas around load order (Atmosphere packages with
bare
files?) that could still run before my head scripts/local package? - Could this be a Babel config issue (e.g.
for..of
transform needing@babel/runtime
or a specific helper) inside Meteor’s build? - Am I barking up the wrong tree and this is not a polyfill problem?
Any guidance or a minimal working config snippet would be hugely appreciated. I can provide more device/browser versions and isolate a repro if that helps. Thanks!