• Stars
    star
    740
  • Rank 58,810 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 4 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Babel preset that targets modern browsers by fixing engine bugs (will be merged into preset-env eventually)

@babel/preset-modules

โ„น๏ธ Starting from @babel/preset-env 7.9.0, you can enable the bugfixes: true option to get the same behavior as using @babel/preset-modules, but with support for custom targets. If you need to target browsers with native modules support (like this preset does), you can use targets: { esmodules: true }.

A Babel preset that enables async/await, Tagged Templates, arrow functions, destructured and rest parameters, and more in all modern browsers (88% of traffic).

It works around bugs and inconsistencies in modern JavaScript engines by converting broken syntax to the closest non-broken modern syntax. Use this in place of @babel/preset-env's target.esmodules option for smaller bundle size and improved performance.

This preset is only useful for browsers. You can serve the output to modern browsers while still supporting older browsers using the module/nomodule pattern:

<!-- transpiled with preset-modules: -->
<script type="module" src="modern.js"></script>
<!-- transpiled with preset-env: -->
<script nomodule src="legacy.js"></script>

Features Supported

  • JSX spread attributes are compiled to Object.assign() instead of a helper.
  • Default, destructured and optional parameters are all natively supported.
  • Tagged Templates are fully supported, patched for Safari 10+ and Edge 16+.
  • async/await is supported without being transpiled to generators.
  • Function name inference works as expected, including Arrow Functions.

Installation & Usage

Install the preset from npm:

npm install @babel/preset-modules --save-dev

To use the preset, add it to your Babel Configuration:

{
  "presets": [
    "@babel/preset-modules"
  ]
}

If you're implementing the module/nomodule pattern, your configuration might look something like this:

{
  "env": {
    "modern": {
      "presets": [
        "@babel/preset-modules"
      ]
    },
    "legacy": {
      "presets": [
        "@babel/preset-env"
      ]
    }
  }
}

Options

There's a single Boolean loose option, which defaults to false. Passing true further reduces output size.

The loose setting turns off a rarely-needed function name workaround for older versions of Edge. If you're not relying on Function.prototype.name, it's worth enabling loose mode.

How does it work?

Babelโ€™s preset-env is great, since it lets you define which Babel features are needed based on a browser support target. In order to make that plumbing work automatically, the preset has configuration that groups all of the new JavaScript syntax features into collections of related syntax transforms. These groups are fairly large, for example "function arguments" includes destructured, default and rest parameters. The groupings come from the fact that Babelโ€™s transforms often rely on other transforms, so they canโ€™t always be applied in isolation.

From this grouping information, Babel enables or disables each group based on the browser support target you specify to preset-envโ€™s targets option. For modern output, the targets.esmodules option is effectively an alias for the set of browsers that support ES Modules: Edge 16+, Safari 10.1+, Firefox 60+ and Chrome 61+.

Here's the problem: if any version of any browser in that list contains a bug triggered by modern syntax, the only solution we have is to enable the corresponding transform group that fixes that bug. This means that fundamentally, preset-env converts code to ES5 in order to get around syntax bugs in ES2017. Since that's the only solution at our disposal, eventually it becomes overused.

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:

// 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:

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

output:

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):

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:

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

With Terser CLI:

terser --ecma 2017 --safari10 ...

With terser-webpack-plugin:

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

All of the above configurations also apply to uglify-es. UglifyJS (2.x and prior) does not support modern JavaScript, so it cannot be used in conjunction with this preset.

More Repositories

1

babel

๐Ÿ  Babel is a compiler for writing next generation JavaScript.
TypeScript
42,835
star
2

babel-loader

๐Ÿ“ฆ Babel loader for webpack
JavaScript
4,794
star
3

minify

โœ‚๏ธ An ES6+ aware minifier based on the Babel toolchain (beta)
JavaScript
4,375
star
4

babel-preset-env

PSA: this repo has been moved into babel/babel -->
JavaScript
3,502
star
5

babel-sublime

Syntax definitions for ES6 JavaScript with React JSX extensions.
JavaScript
3,260
star
6

babel-eslint

๐Ÿ—ผ A wrapper for Babel's parser used for ESLint (renamed to @babel/eslint-parser)
JavaScript
2,970
star
7

example-node-server

Example Node Server w/ Babel
JavaScript
2,842
star
8

babylon

PSA: moved into babel/babel as @babel/parser -->
JavaScript
1,714
star
9

babelify

Browserify transform for Babel
JavaScript
1,680
star
10

gulp-babel

Gulp plugin for Babel
JavaScript
1,322
star
11

babel-upgrade

โฌ†๏ธ A tool for upgrading Babel versions (to v7): `npx babel-upgrade`
JavaScript
1,308
star
12

awesome-babel

๐Ÿ˜ŽA list of awesome Babel plugins, presets, etc.
857
star
13

babel-standalone

๐ŸŽฎ Now located in the Babel repo! Standalone build of Babel for use in non-Node.js environments, including browsers.
JavaScript
821
star
14

website

๐ŸŒ The Babel documentation website
TypeScript
740
star
15

kneden

Transpile ES2017 async/await to vanilla ES6 Promise chains: a Babel plugin
JavaScript
514
star
16

grunt-babel

Grunt plugin for Babel
JavaScript
438
star
17

proposals

โœ๏ธ Tracking the status of Babel's implementation of TC39 proposals (may be out of date)
433
star
18

eslint-plugin-babel

An ESlint rule plugin companion to babel-eslint
JavaScript
390
star
19

generator-babel-boilerplate

A Yeoman generator to author libraries in ES2015 (and beyond!) for Node and the browser.
JavaScript
381
star
20

babel-time-travel

Time travel through babel transformations one by one (implemented in the Babel REPL now)
JavaScript
345
star
21

babel-polyfills

A set of Babel plugins that enable injecting different polyfills with different strategies in your compiled code.
TypeScript
321
star
22

babel-sublime-snippets

Next generation JavaScript and React snippets for Sublime
264
star
23

karma-babel-preprocessor

Karma plugin for Babel
JavaScript
167
star
24

ruby-babel-transpiler

Ruby Babel is a bridge to the JS Babel transpiler.
Ruby
158
star
25

babel-jest

Jest plugin for Babel (moved) ->
139
star
26

notes

โ™ฌ Notes from the @Babel Team (discuss in PRs)
121
star
27

generator-babel-plugin

Babel Plugin generator for Yeoman
JavaScript
118
star
28

babel-bridge

A placeholder package that bridges babel-core to @babel/core.
JavaScript
94
star
29

babel-bot

๐Ÿค– A helpful bot to automate common tasks on Babel Issues/PRs
JavaScript
75
star
30

babel-brunch

Brunch plugin for Babel
JavaScript
69
star
31

broccoli-babel-transpiler

Broccoli plugin for Babel
JavaScript
58
star
32

jade-babel

Jade plugin for Babel
JavaScript
40
star
33

sandboxes

Babel repl-like codesandbox: check out link =>
JavaScript
39
star
34

jekyll-babel

A Babel converter for Jekyll.
Ruby
34
star
35

acorn-to-esprima

(unmaintained) Converts acorn tokens to esprima tokens
JavaScript
33
star
36

babel-connect

Connect plugin for Babel
JavaScript
27
star
37

podcast.babeljs.io

The Babel Podcast site!
JavaScript
25
star
38

phabricator-to-github

A tool to migrate phabricator issues to github
JavaScript
24
star
39

actions

Babel specific github actions ๐Ÿค–
JavaScript
24
star
40

rfcs

RFCs for changes to Babel
21
star
41

metalsmith-babel

A Metalsmith plugin to compile JavaScript with Babel
JavaScript
20
star
42

babel-configuration-examples

WIP
JavaScript
18
star
43

duo-babel

Duo plugin for Babel
JavaScript
16
star
44

logo

Babel logo
15
star
45

parser_performance

JavaScript
13
star
46

babel-standalone-bower

Bower build of babel-standalone. See https://github.com/Daniel15/babel-standalone
JavaScript
10
star
47

gobble-babel

Gobble plugin for Babel
JavaScript
9
star
48

eslint-config-babel

ESLint config for all Babel repos
JavaScript
9
star
49

eslint-plugin-babel-plugin

A set of eslint rules to enforce best practices in the development of Babel plugins.
JavaScript
8
star
50

flavortown

what else?
7
star
51

.github

Community health files for the Babel organization
7
star
52

babel-archive

๐Ÿ—‘ Packages that are deprecated or don't need to be updated
JavaScript
6
star
53

babel-test262-runner

Run test262 tests on Node 0.10 using Babel 7 and `core-js@3`.
JavaScript
6
star
54

babel-plugin-proposal-private-property-in-object

@babel/plugin-proposal-private-property-in-object, with an added warning for when depending on this package without explicitly listing it in dependencies or devDependencies
JavaScript
6
star
55

phabricator-redirects

โ†ฉ๏ธ Redirects for old phabricator urls
HTML
5
star
56

babel-plugin-transform-async-functions

https://github.com/MatAtBread/fast-async/issues/46
4
star
57

slack-invite-link

Source of slack.babeljs.io
1
star