d.

For example, all of the new syntax features relating to function parameters are grouped into the same Babel plugin (`@babel/plugin-transform-function-parameters`). That means because Edge 16 & 17 support ES Modules but have a bug related to parsing shorthand destructured parameters with default values within arrow functions, all functions get compiled from the new compact argument syntaxes down to ES5:

```js
// this breaks in Edge 16:
const foo = ({ a = 1 }) => {};

// .. but this doesn't:
function foo({ a = 1, b }, ...args) {}

// ... and neither does this:
const foo = ({ a: a = 1 }) => {};
```

In fact, there are 23 syntax improvements for function parameters in ES2017, and only one of them is broken in ES Modules-supporting browsers. It seems unfortunate to transpile all those great features down to ES5 just for one browser!

This plugin takes a different approach than we've historically taken with JavaScript: it transpiles the broken syntax to the closest _non-broken modern syntax_. In the above case, here's what is generated to fix all ES Modules-supporting browsers:

**input:**

```js
const foo = ({ a = 1 }, b = 2, ...args) => [a,b,args];
```

**output:**

```js
const foo = ({ a: a = 1 }, b = 2, ...args) => [a,b,args];
```

That output works in all ES Modules-supporting browsers, and is only **59 bytes** minified & gzipped.

> Compare this to `@babel/preset-env`'s `targets.esmodules` output (**147 bytes** minified & gzipped):
>
> ```js
>const foo = function foo(_ref, b) {
>  let { a = 1 } = _ref;
>
>  if (b === void 0) { b = 2; }
>
>  for (
>    var _len = arguments.length,
>      args = new Array(_len > 2 ? _len - 2 : 0),
>      _key = 2;  _key < _len; _key++
>  ) {
>    args[_key - 2] = arguments[_key];
>  }
>
>  return [a, b, args];
>};
>````

The result is improved bundle size and performance, while supporting the same browsers.


### Important: Minification

The output generated by this preset includes workarounds for Safari 10, however minifiers like Terser sometimes remove these workarounds. In order to avoid shipping broken code, it's important to tell Terser to preserve the workarounds, which can be done via the `safari10` option.

It's also generally the case that minifiers are configured to output ES5 by default, so you'll want to change the output syntax to ES2017.

With [Terser's Node API](https://github.com/terser/terser#minify-options):

```js
terser.minify({
  ecma: 2017,
  safari10: true
})
```

With [Terser CLI](https://npm.im/terser):

```sh
terser --ecma 2017 --safari10 ...
```

With [terser-webpack-plugin](https://webpack.js.org/plugins/terser-webpack-plugin/):

```js
module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          ecma: 2017,
          safari10: true
        }
      })
    ]
  }
};
```

All of the above configurations also apply to [uglify-es](https://github.com/mishoo/UglifyJS2/tree/harmony).
UglifyJS (2.x and prior) does not support modern JavaScript, so it cannot be used in conjunction with this preset.
