Polyfill esnext.async-iterator causes "Cannot read properties of undefined (reading 'prototype')" error
qiulang opened this issue · comments
My Babel
"presets": [
[
"@babel/preset-env",
{
"targets": {
"chrome": "84"
},
"modules": "commonjs",
"debug": true,
"useBuiltIns": "usage",
"corejs": {
"version": 3.8
"proposals": true
}
}
]
]
Then from log, I saw
[/Users/langqiu/xxx/getLoginInfo.js]
The corejs3 polyfill added the following polyfills:
es.aggregate-error { "chrome":"84" }
es.promise.any { "chrome":"84" }
esnext.async-iterator.map { "chrome":"84" }
esnext.iterator.map { "chrome":"84" }
esnext.async-iterator.filter { "chrome":"84" }
esnext.iterator.constructor { "chrome":"84" }
esnext.iterator.filter { "chrome":"84" }
This polyfilled file cause the error Uncaught TypeError: Cannot read properties of undefined (reading 'prototype')
async-iterator-create-proxy.js:42 Uncaught TypeError: Cannot read properties of undefined (reading 'prototype')
at e.exports (async-iterator-create-proxy.js:42:72)
at Object.<anonymous> (esnext.async-iterator.map.js:8:26)
at n (bootstrap:19:22)
at Object.<anonymous> (getLoginInfo.js:1:13)
...
at bootstrap:83:10
Only after I set "proposals": false
and poyfill without async-iterator the code works, but why?
I feel this may be a bug for async-iterator implementation.
[/Users/langqiu/xxx/getLoginInfo.js]
The corejs3 polyfill added the following polyfills:
es.aggregate-error { "chrome":"84" }
es.promise.any { "chrome":"84" }
What core-js
version is used? In what engine you have this error? Could you add a reproducible example?
Note that the line numbers in the stack are not actual and in this file (and in this function) is only one place where we access .prototype
, and it can't cause any problems:
module.exports = function (nextHandler, IS_ITERATOR) {
var AsyncIteratorProxy = function AsyncIterator(record, state) {
// ...
};
AsyncIteratorProxy.prototype = IS_ITERATOR ? WrapForValidAsyncIteratorPrototype : AsyncIteratorHelperPrototype;
return AsyncIteratorProxy;
};
Yes, let me create a reproducible example later. It is reproducible from my side.
As you can see in the code above, the problem is missing in the actual (3.33.3) version. It seems that in this old (3.8) version was an implicit undeclared dependency of esnext.async-iterator.*
from esnext.async-iterator.constructor
that was fixed later. You should use the actual version since old versions are not maintained.
But in the 3.33 version, I can see from the log esnext.async-iterator.* is not polyfilled into the , I think that is the reason 3.33 works.
I'm not sure that I understood you. They should be injected in case of .map
or .filter
usage with proposals: true
. Overwise, it's a Babel, not core-js
, issue.
I think that is the reason 3.33 works
The actual core-js
versions work since they have access to %AsyncIteratorPrototype%
in another way, without esnext.async-iterator.constructor
implicit dependency. IIRC it was a bug that was fixed about 3 years ago.
In case they are just missed on %AsyncIteratorPrototype%
- check the readme, that requires extra configuration.
Thanks for the reply. Yes, you were right, with 3.33, they are injected and the bundled file works fine!
[/Users/langqiu/Projects/xxx/getLoginInfo.js]
The corejs3 polyfill added the following polyfills:
es.aggregate-error { "chrome":"84" }
es.promise.any { "chrome":"84" }
esnext.async-iterator.map { "chrome":"84" }
esnext.iterator.map { "chrome":"84" }
esnext.async-iterator.filter { "chrome":"84" }
esnext.iterator.constructor { "chrome":"84" }
esnext.iterator.filter { "chrome":"84" }
Thanks again.
BTW, I will raise an issue to https://babeljs.io/docs/babel-preset-env#corejs too, because it says, "use corejs: { version: "3.8", proposals: true }. " It should emphasize setting the version to the actual core-js version.
May I ask another question? What do these esnext.async-iterator
functions provide that Chrome lacks?
I find even with the recent Chome version 114, they are still polyfill. But I find without these polyfill functions my code work just fine.
[/Users/langqiu/xxx/getLoginInfo.js]
The corejs3 polyfill added the following polyfills:
esnext.async-iterator.map { "chrome":"114" }
esnext.iterator.map { "chrome":"114" }
esnext.async-iterator.filter { "chrome":"114" }
esnext.iterator.constructor { "chrome":"114" }
esnext.iterator.filter { "chrome":"114" }
Those features are still missed in any engines, see https://github.com/tc39/proposal-async-iterator-helpers
Most likely, you do not use them and use just Array#{ filter, map }
methods - but since in JS in many cases is impossible to determinate a variable type on static analysis (@babel/preset-env
works by this way), Babel inject some extra modules which there is a chance that you are using - it's better to load some extra bytes than break your project because something is missing.
import foo from './foo.js';
console.log(...foo.map(it => it ** 2)); // => what is it - Array#map, Iterator#map, AsyncIterator#map, something else?
I don't recommend to use proposals: true
, it's just for experimenting. shippedProposals
is much better and safer for most cases.