💻
How are you using Babel?
babel-loader (webpack)
Input code
class MyClass {
[Symbol.iterator]() {
return {
next: () => ({ value: 1, done: false })
};
}
}
const a = new MyClass();
console.log(a);
for (const i of document.querySelectorAll('h1')) {
console.log(i);
}
if (typeof Symbol() === 'symbol') console.log('is a symbol');
Configuration file name
.babelrc.js
Configuration
This is my .babelrc.js file:
module.exports = {
presets: [
[
'@babel/preset-env',
{
// "exclude": ["transform-typeof-symbol"],
bugfixes: true,
loose: false,
modules: false,
useBuiltIns: 'usage',
corejs: {
version: require('core-js/package.json').version,
proposals: false,
},
shippedProposals: true,
}
]
],
}
This is the output when using BABEL_SHOW_CONFIG_FOR=...
{
"presets": [
[
"@babel/preset-env",
{
"bugfixes": true,
"loose": false,
"modules": false,
"useBuiltIns": "usage",
"corejs": {
"version": "3.39.0",
"proposals": false
},
"shippedProposals": true
}
]
]
}
Browserslist config is in package.json:
{
// ...
"browserslist": [
"chrome >= 38"
],
// ...
}
Current and expected behavior
Currently, the output from babel includes the core-js/es.symbol.js import but, the helper for _keyof is not added. This causes that keyof Symbol() returns "object", and when defining [Symbol.iterator]() on the class, the app crashes because _toPrimitive helper throws an error (Symbol.iterator[Symbol.toPrimitive]() returns "object").
What I expect is the app not to crash.
Environment
System:
OS: macOS 14.7.1
Binaries:
Node: 22.11.0 - ~/.nvm/versions/node/v22.11.0/bin/node
npm: 10.9.2 - ~/.nvm/versions/node/v22.11.0/bin/npm
npmPackages:
@babel/cli: ^7.26.4 => 7.26.4
@babel/core: ^7.26.0 => 7.26.0
@babel/preset-env: ^7.26.0 => 7.26.0
babel-loader: ^9.2.1 => 9.2.1
webpack: ^5.97.1 => 5.97.1
Possible solution
- When Symbol polyfill is added, the "keyof-symbol" transform should also be added.
- To not add Symbol polyfill when targeting Chrome 38.
Additional context
When the code doesn't use for...of syntax the Symbol polyfill is not added so the error doesn't happen. It looks like, this polyfill is added to patch a specific behavior on Symbol when for...of syntax is used.
There are two workarounds for this:
- To target
"Chrome >= 37". With this, we force the "keyof-symbol" transform to be applied so _toPrimitive helper will not throw.
- Apply
setPublicClassFields assumption. With this, _defineProperties helper is not used, and therefore _toPrimitive is not called with Symbol.iterator.
See more information: vitejs/vite#18959 (comment)
💻
How are you using Babel?
babel-loader (webpack)
Input code
Configuration file name
.babelrc.js
Configuration
This is my
.babelrc.jsfile:This is the output when using
BABEL_SHOW_CONFIG_FOR=...{ "presets": [ [ "@babel/preset-env", { "bugfixes": true, "loose": false, "modules": false, "useBuiltIns": "usage", "corejs": { "version": "3.39.0", "proposals": false }, "shippedProposals": true } ] ] }Browserslist config is in package.json:
{ // ... "browserslist": [ "chrome >= 38" ], // ... }Current and expected behavior
Currently, the output from babel includes the
core-js/es.symbol.jsimport but, the helper for_keyofis not added. This causes thatkeyof Symbol()returns"object", and when defining[Symbol.iterator]()on the class, the app crashes because_toPrimitivehelper throws an error (Symbol.iterator[Symbol.toPrimitive]()returns"object").What I expect is the app not to crash.
Environment
Possible solution
Additional context
When the code doesn't use
for...ofsyntax theSymbolpolyfill is not added so the error doesn't happen. It looks like, this polyfill is added to patch a specific behavior on Symbol whenfor...ofsyntax is used.There are two workarounds for this:
"Chrome >= 37". With this, we force the "keyof-symbol" transform to be applied so_toPrimitivehelper will not throw.setPublicClassFieldsassumption. With this,_definePropertieshelper is not used, and therefore_toPrimitiveis not called withSymbol.iterator.See more information: vitejs/vite#18959 (comment)