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]: [@babel/preset-env] In Safari, arrow functions with ...args as function parameter always get transpiled regardless of Safari version #13916

Closed
1 task
peripateticus opened this issue Nov 2, 2021 · 5 comments
Labels
i: needs triage outdated A closed issue/PR that is archived due to age. Recommended to make a new issue

Comments

@peripateticus
Copy link

peripateticus commented Nov 2, 2021

💻

  • Would you like to work on a fix?

How are you using Babel?

@babel/cli

Input code

// Regardless of your browserslist versions for Safari, this code's outer function is always transpiled to a plain function (see below) 
module.exports = {
  add: (...args) => args.reduce((acc, val) => acc + val),
};
// Transpiled code
module.exports = {
  add: function () {
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return args.reduce((acc, val) => acc + val);
  }
};

Configuration file name

No response

Configuration

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "useBuiltIns": "usage",
        "corejs": 3,
        "targets": [
            "safari >= 15"
        ]
      }
    ]
  ]
}

Current and expected behavior

On our current versions of Babel dependencies specified in our lockfile, this code does not get transpiled and passes through, as is. After updating to latest @babel/preset-env (7.16.0), it's now being transpiled. This also doesn't seem correct because all of the syntax in the code is supported in the Safari version specified (15, in this case). It doesn't seem to matter which version of Safari you specify, it always transpiles outer function with the ...args but leaves inner arrow intact.

It appears to be another child dependency that is controlling this other than @babel/preset-env and @babel/core but not sure which as many Babel dependencies get updated when updating @babel/preset-env. So, for example, if I just install versions of @babel/preset-env and @babel/core, per our package-lock, it still transpiles that arrow with ...args to a regular function.

We caught this because unit tests that were once passing now fail as this code is getting transpiled when it shouldn't be according to our browserslist config.

Environment

  • Babel
    • @babel/preset-env 7.14.8
    • @babel/core 7.14.8
    • @babel/cli 7.14.3
  • Node 12.13.0
  • MacOS 10.15.7

Possible solution

No response

Additional context

I have a feeling that this is related to a version of a child dependency locked at a particular version so is difficult to reproduce without sending you the entire lockfile. Let me know which dependencies would affect this and I can send you what our lockfile is showing.

@babel-bot
Copy link
Collaborator

Hey @peripateticus! 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.

@JLHwung
Copy link
Contributor

JLHwung commented Nov 2, 2021

Can you update browserslists to the latest version? The browserslists comes with a caniuse-lite package which tells browserslists the currently known Safari versions.

My guess here is that if Safari >= 14 works for you, then the caniuse-lite may be out-of-dated and browserslists thinks that Safari >= 15 is unknown Safari versions, which causes Babel fallbacks to applying all transforms.

You can also add debug: true to the preset-env options, which will print the resolved browsers targets.

Related: #13912

Will be fixed in #13914

@peripateticus
Copy link
Author

peripateticus commented Nov 2, 2021

Looks like I'm on the latest browserslist:

├─┬ @babel/core@7.16.0
│ └─┬ @babel/helper-compilation-targets@7.16.0
│   └── browserslist@4.17.5
└─┬ @babel/preset-env@7.16.0
  └─┬ core-js-compat@3.19.0
    └── browserslist@4.17.5  deduped

Running with debug: true, here's what I'm seeing:

@babel/preset-env: `DEBUG` option

Using targets:
{
  "safari": "15"
}

Using modules transform: false

Using plugins:
  proposal-class-static-block { safari }
  syntax-private-property-in-object
  syntax-class-properties
  syntax-numeric-separator
  syntax-nullish-coalescing-operator
  syntax-optional-chaining
  syntax-json-strings
  syntax-optional-catch-binding
  transform-parameters { safari }
  syntax-async-generators
  syntax-object-rest-spread
  proposal-export-namespace-from { safari }
  syntax-dynamic-import
corejs3: `DEBUG` option

Using targets: {
  "safari": "15"
}

Using polyfills with `usage-global` method:

[/prj/babel/bug.js]
Based on your code and targets, the corejs3 polyfill did not add any polyfill.
module.exports = {
  add: function () {
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return args.reduce((acc, val) => acc + val);
  }
};

Updated browserslist db as well:

╰─ npx browserslist@latest --update-db                                                      [ 6:32PM Mon Nov  1 ]
npx: installed 6 in 2.03s
Latest version:     1.0.30001274
Installed version:  1.0.30001274
caniuse-lite is up to date
caniuse-lite has been successfully updated

No target browser changes

@JLHwung
Copy link
Contributor

JLHwung commented Nov 2, 2021

transform-parameters { safari }

The parameter transform kicks in because Safari has a bug on transforming parameters: https://bugs.webkit.org/show_bug.cgi?id=220517

You can add bugfixes: true to the preset-env options to tell Babel: only transform parameters when the input code is actually affected by this bug. This will be enabled by default on Babel 8.

@peripateticus
Copy link
Author

peripateticus commented Nov 2, 2021

Yep that did it! adding bugfixes: true to the present-env option output:

@babel/preset-env: `DEBUG` option

Using targets:
{
  "safari": "15"
}

Using modules transform: false

Using plugins:
  proposal-class-static-block { safari }
  syntax-private-property-in-object
  syntax-class-properties
  syntax-numeric-separator
  syntax-nullish-coalescing-operator
  syntax-optional-chaining
  syntax-json-strings
  syntax-optional-catch-binding
  syntax-async-generators
  syntax-object-rest-spread
  proposal-export-namespace-from { safari }
  bugfix/transform-safari-id-destructuring-collision-in-function-expression { safari }
  syntax-dynamic-import
corejs3: `DEBUG` option

Using targets: {
  "safari": "15"
}

Using polyfills with `usage-global` method:

[/prj/babel/bug.js]
Based on your code and targets, the corejs3 polyfill did not add any polyfill.
module.exports = {
  add: (...args) => args.reduce((acc, val) => acc + val)
};

Thanks for your help on this @JLHwung! Closing this one out.

@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Feb 1, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
i: needs triage outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
Development

No branches or pull requests

3 participants