Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Array.prototype.at parse wrong with babel/cli #112

Open
1 task
lyz810 opened this issue Jan 12, 2022 · 4 comments
Open
1 task

[Bug]: Array.prototype.at parse wrong with babel/cli #112

lyz810 opened this issue Jan 12, 2022 · 4 comments
Labels
question Further information is requested

Comments

@lyz810
Copy link

lyz810 commented Jan 12, 2022

💻

  • Would you like to work on a fix?

How are you using Babel?

@babel/cli

Input code

case 1(wrong result)

function test() {
    this.array = [];
    var lastIndexOfArray = this.array.at(-1);
}

output:

import "core-js/modules/esnext.string.at.js"; // should be import "core-js/modules/es.array.at.js"

function test() {
  this.array = [];
  var lastIndexOfArray = this.array.at(-1);
}

case 2 (wrong result)

function test() {
    var array = [];
    var lastIndexOfArray = array.at(-1);
}

output(same as input, no core-js added):
function test() {
  var array = [];
  var lastIndexOfArray = array.at(-1);
}

case 3(parse as expected)

function test() {
    var string = '123';
    var lastIndexOfString = string.at(-1);
}

output:
import "core-js/modules/esnext.string.at.js";

function test() {
  var string = '123';
  var lastIndexOfString = string.at(-1);
}

case 4(parse as expected)

function test() {
    this.string = '123';
    var lastIndexOfString = string.at(-1);
}

output:
import "core-js/modules/esnext.string.at.js";

function test() {
  this.string = '123';
  var lastIndexOfString = string.at(-1);
}

Configuration file name

No response

Configuration

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "useBuiltIns": "usage",
        "targets": {
          "chrome": 43,
          "ios": 9,
          "edge": 80,
          "firefox": 60
        },
        "corejs": {
          "proposals": true,
          "version": 3
        }
      }
    ],
    "@babel/preset-react"
  ]
}

Current and expected behavior

add corejs es.array.at.js, not esnext.string.at.js

recognize Array.prototype.at

Environment

System:
OS: macOS 11.6.1
Binaries:
Node: 16.13.0 - /usr/local/bin/node
npm: 8.1.0 - /usr/local/bin/npm
npmPackages:
@babel/cli: ^7.16.8 => 7.16.8
@babel/core: ^7.16.7 => 7.16.7
@babel/eslint-parser: ^7.16.5 => 7.16.5
@babel/plugin-proposal-decorators: ^7.16.7 => 7.16.7
@babel/plugin-transform-runtime: ^7.16.8 => 7.16.8
@babel/preset-env: ^7.16.8 => 7.16.8
@babel/preset-react: ^7.16.7 => 7.16.7
@babel/preset-typescript: ^7.16.7 => 7.16.7
@babel/runtime: ^7.16.7 => 7.16.7
babel-jest: ^27.4.6 => 27.4.6
babel-preset-const-enum: ^1.0.0 => 1.0.0
eslint: ^8.6.0 => 8.6.0
jest: ^27.4.7 => 27.4.7

Possible solution

No response

Additional context

No response

@babel-bot
Copy link

Hey @lyz810! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite.

@lyz810
Copy link
Author

lyz810 commented Jan 12, 2022

{
"corejs": {
   "proposals": true,
   "version": "3.20.2"
}

this config can add import "core-js/modules/es.array.at.js";
but also will add

import "core-js/modules/es.string.at-alternative.js";
import "core-js/modules/esnext.string.at.js";

should only add es.array.at

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Jan 12, 2022

It's not that easy. Consider this example:

function test() {
    this.array = [];
    var lastIndexOfArray = this.array.at(-1);
}

If somewhere else in your application (maybe even in a different file!) you do something like this:

Object.defineProperty(test.prototype, "array", {
  set: () => {},
  get: () => "hello!",
});

then the this.array.at(-1) call is calling .at on a string and not on an array. Whenever we see .at being used, unless we can be 100% sure that we are handling a string/array we should inject both.

As you noticed, when you specify "version": "3.20.2" we inject the Array.prototype.at polyfill: this is because it's not supported by every core-js@3 version, so we cannot inject it by default. I suggest always specifying the exact core-js version you are using.

When specifying a modern core-js version, I would expect that:

  • The first example loads both the polyfills
  • The second example only loads the array polyfill (because we can statically verify that array is an array)
  • The third example only loads the strings polyfill (because we can statically verify that string is a string)
  • The fourth example loads both the polyfill

I don't know what's the difference between es.string.at and es.string.at-alternative, but maybe @zloirock can reply to that.

@nicolo-ribaudo nicolo-ribaudo transferred this issue from babel/babel Jan 12, 2022
@nicolo-ribaudo nicolo-ribaudo added the question Further information is requested label Jan 12, 2022
@zloirock
Copy link
Member

esnext.string.at is a module for an obsolete proposal that worked with multibyte symbols.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants