Transpile ES7 features to ES5
BabelJS - Transpiling ES2016 (ES7) Features to ES5
Section titled “BabelJS - Transpiling ES2016 (ES7) Features to ES5”ECMAScript 2016 (formerly ES7) introduced a couple of notable features to JavaScript. While modern browsers have good support for these, you might need to transpile them to ES5 if you’re targeting older environments. BabelJS, particularly with @babel/preset-env, handles these transformations.
The main features added in ES2016 are:
- Exponentiation Operator (
**) - Array.prototype.includes()
(Note: Async/Await, often associated with this era, was officially standardized in ES2017. We’ll cover its transpilation separately or as part of ES2017 features, but the principles are similar.)
We’ll focus on transpiling these to ES5. By default, @babel/preset-env without specific targets will transpile to ES5. For features like Array.prototype.includes(), Babel can’t just transpile syntax; it’s a new method. This requires a polyfill.
1. Exponentiation Operator (**)
Section titled “1. Exponentiation Operator (**)”The exponentiation operator provides a shorthand for Math.pow().
ES2016 Code (example: exponentiation.js)
Section titled “ES2016 Code (example: exponentiation.js)”let num = 2;let powerOfThree = num ** 3; // 2 to the power of 3console.log(`${num} raised to the power of 3 is ${powerOfThree}`); // Outputs: 2 raised to the power of 3 is 8
let squared = 5 ** 2;console.log(`5 squared is ${squared}`); // Outputs: 5 squared is 25To transpile this, ensure you have Babel configured (e.g., with babel.config.json using @babel/preset-env).
Babel Configuration (babel.config.json)
Section titled “Babel Configuration (babel.config.json)”{ "presets": ["@babel/preset-env"]}Transpilation Command
Section titled “Transpilation Command”npx babel exponentiation.js --out-file exponentiation_es5.jsTranspiled ES5 Code (exponentiation_es5.js)
Section titled “Transpiled ES5 Code (exponentiation_es5.js)”"use strict";
var num = 2;var powerOfThree = Math.pow(num, 3); // 2 to the power of 3
console.log("".concat(num, " raised to the power of 3 is ").concat(powerOfThree)); // Outputs: 2 raised to the power of 3 is 8
var squared = Math.pow(5, 2);console.log("5 squared is ".concat(squared)); // Outputs: 5 squared is 25Babel correctly converts the ** operator to its Math.pow() equivalent, which is available in all ES5 environments.
2. Array.prototype.includes()
Section titled “2. Array.prototype.includes()”Array.prototype.includes() is a convenient method to check if an array contains a certain element, returning true or false. Unlike the exponentiation operator, this is a new method on Array.prototype. Babel cannot simply transpile syntax for this; it requires a polyfill to provide the includes method functionality in environments where it’s missing.
ES2016 Code (example: array_includes.js)
Section titled “ES2016 Code (example: array_includes.js)”let numbers = [1, 2, 3, 4, 5];console.log(numbers.includes(3)); // trueconsole.log(numbers.includes(6)); // false
let pets = ['cat', 'dog', 'bat'];console.log(pets.includes('cat')); // trueconsole.log(pets.includes('hamster')); // falseIf you transpile this code with Babel using only @babel/preset-env without polyfill configuration, the JavaScript syntax itself (the method call) will remain largely unchanged because it’s valid syntax. However, it won’t work in an old browser that doesn’t have Array.prototype.includes.
Transpiled ES5 Code (Syntactically, without polyfill applied yet)
Section titled “Transpiled ES5 Code (Syntactically, without polyfill applied yet)”"use strict";
var numbers = [1, 2, 3, 4, 5];console.log(numbers.includes(3)); // true in modern env, error or undefined in old envconsole.log(numbers.includes(6)); // false in modern env, error or undefined in old env
var pets = ['cat', 'dog', 'bat'];console.log(pets.includes('cat')); // trueconsole.log(pets.includes('hamster')); // falseMaking it Work with Polyfills
Section titled “Making it Work with Polyfills”To make Array.prototype.includes() work in older environments, you need to provide a polyfill. The recommended way with modern Babel is to use core-js. You can configure @babel/preset-env to automatically include polyfills from core-js based on usage and your target environments.
- Install
core-js:
npm install --save core-js- Update
babel.config.json:
{ "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage", // or "entry" "corejs": 3 // Specify core-js version } ] ]}With "useBuiltIns": "usage", Babel will analyze your code and add specific import 'core-js/...' statements only for the features you use that are not supported by your target environments. If no targets are specified, it assumes older environments.
When you transpile array_includes.js now, Babel will prepend imports like:
// Example of what Babel might add at the top of array_includes_es5.js:// import "core-js/modules/es.array.includes.js";// (if using a bundler, otherwise it might be different)
"use strict";// ... rest of your transpiled code ...var numbers = [1, 2, 3, 4, 5];console.log(numbers.includes(3));// ...This imported core-js module provides the Array.prototype.includes implementation if it’s missing. Now, the code will work correctly even in older browsers that support ES5 but lack includes.
Alternatively, using "useBuiltIns": "entry" requires you to add import "core-js"; and import "regenerator-runtime/runtime"; (if using async/generators) at the entry point of your application. Babel will then replace these with specific imports based on your targets.
Testing in a Browser
Section titled “Testing in a Browser”To test polyfilled code in a browser, you’d typically bundle your JavaScript (e.g., using Webpack or Rollup), which resolves the import statements for core-js. Your HTML would then include this bundle.
test.html (assuming bundled output bundle.js):
<!DOCTYPE html><html><head> <title>BabelJS ES2016 Test</title></head><body> <p>Check the console for output.</p> <script src="bundle.js"></script> <!-- bundle.js would contain transpiled code + core-js polyfills --></body></html>When you open this HTML in an older browser, the console should correctly show:
truefalsetruefalseThis demonstrates the power of Babel not just for syntax transformation but, in conjunction with polyfill libraries like core-js, for providing missing functionalities in older JavaScript environments.
For more details on polyfilling, refer to the dedicated chapter on Polyfills and the official Babel and core-js documentation.