Skip to content

[Bug]: When targeting Chrome 38 Symbol polyfill is included but not "typeof-symbol" transform #17030

@cdatehortuab

Description

@cdatehortuab

💻

  • Would you like to work on a fix?

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    outdatedA closed issue/PR that is archived due to age. Recommended to make a new issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions