Closed everdimension closed 1 year ago
That's not for...of
being polyfilled, but your non-iterable (in the target format, anyway) being polyfilled.
For example,
input
const arr = [1, 2, 3];
for (const el of arr) { console.log(el); }
> CJS output
```js
var arr = [1, 2, 3];
for (var _i = 0, _arr = arr; _i < _arr.length; _i++) {
var el = _arr[_i];
console.log(el);
}
input
const arr = 'foo';
for (const el of arr) { console.log(el); }
> CJS output
```js
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
if (it) return (it = it.call(o)).next.bind(it);
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var arr = 'foo';
for (var _iterator = _createForOfIteratorHelperLoose(arr), _step; !(_step = _iterator()).done;) {
var el = _step.value;
console.log(el);
}
This is clearer if you disable compression with the --no-compress
flag, or --target node
.
My compilation target is esnext (defined in tsconfig.json)
Your tsconfig.json
only controls TS-specific compilation, and even then, it's mostly done through Microbundle's flags instead (like JSX pragma). cjs
, umd
, and esm
are ES5 targetting, while modern
is ES2017. What you set as your tsconfig.json
compilation target doesn't affect anything.
I thought all browsers already support it
Just to add the earlier examples, this isn't so much for...of
not being able to be transpiled in a byte-concious way, but you're iterating over something that needs a helper to be iterable in ES5. Options include changing data structures (if possible) or pointing users at the more modern output, and calling the verbose ES5 as simply legacy cost.
I believe using --format modern
avoids this downleveling. The esm+cjs+umd bundles are ES5.
Yes, the modern
output format is just as terse as the source.
Going to close this out as everything seems to be working as intended from microbundle's side.
Feel free to respond if you have any further issues.
Yes, this answers my question, thanks @rschristian @developit!
Small comment, the value I'm iteraring over is the arguments
object, which seemingly doesn't require conversion if you fallback to a classic for-loop
But I suppose the complier can't make that decision
Hi! I noticed in my project that if I use a
for of
loop instead of a regularfor
loop, microbundle adds approx. 300 bytes of polyfill code:My compilation target is
esnext
(defined intsconfig.json
)Is there a way to tell microbundle to omit this polyfill? I thought all browsers already support it: https://kangax.github.io/compat-table/es6/