JavaScript is a language that is evolving very quickly and sometimes we want to use its latest features, but if our browser or environment doesn't allow it directly, we'll have to transpile it in order for it to do it.
Transpiling is the transformation of source code written in one language into another language with a comparable level of abstraction. Hence, in the case of JavaScript, the transpiler takes syntax that older browsers don't understand and turns it into syntax that they understand.
Polyfilling vs. Transpiling
Both methods work for the same purpose: we can write code that uses new features that are not implemented in our target environment, and then apply one of these methods.
A polyfill is a piece of code that implements modern features so that they can be applied to work in older versions of the browser.
Transpiling is a combination of two words: transforming and
compiling. Sometimes a new syntax cannot be implemented with polyfills, in which case we use a transpiler.
Let's imagine we are using an old browser that does not support the Number.isNaN functionintroduced in the ES6 specification. To use this feature, we need to create a polyfill for this method, but we'll only need this if it's not already available in the browser.
To do this, we will create a function that mimics the behavior of the isNaN function and add it to the Number property of the prototype.
// isNaN
if (!Number.isNan) {// .
Number.prototype.isNaN = function isNaN(n) {
return n !== n;
};
}
let myNumber = 100;
console.log(myNumber.isNaN(100));
We are now going to transpile the code for the newly created function. Let's imagine that most browsers cannot fulfill this function, in which case we cannot create a polyfill to simulate the behavior. We want to run the following code in Internet Explorer 11, so we are going to transform it using a transpiler:
class mySuperClass {
constructor(name) {
this.name = name;
}
hello() {
return "Hello:" +this.name;
}
}
const mySuperClassInstance = new mySuperClass("Rick");
console.log(mySuperClassInstance.hello());
//Hello Rick
The resulting code has been ported using Babel's online transpiler , and we can now execute it in Internet Explorer 11:
"use strict";
function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }
function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var mySuperClass = /*#__PURE__*/function () {
function mySuperClass(name) {
_classCallCheck(this, mySuperClass);
this.name = name;
}
_createClass(mySuperClass, [{
key: "hello",
value: function hello() {
return "Hello:" + this.name;
}
}]);
return mySuperClass;
}();
var mySuperClassInstance = new mySuperClass("Rick");
console.log(mySuperClassInstance.hello()); //Hello Rick
One of the most common JavaScript transpilers is Babel. Babel is a tool that was built to help port your code between different versions of JavaScript and can be installed via the Node Package Manager (npm).
Babel has become the standard for compiling ECMAScript applications into a version of ECMAScript that works in browsers that do not support such applications. Babel can compile other ECMAScript versions like React JSX.
In the next steps, we'll see how to use Babel to transpile and execute the previous mySuperMethod class on a Linux machine with the old Node.js installed . On other operating systems, such as Windows 10 or macOS, the steps are similar.
Note. You must have Node.js installed on your computer . Npm has been added as a function to the Node.js installer
1. Open a command prompt and create a directory called babelExample:
/mkdir babelExample
/cd babelExample
2. Create an npm project and leave the defaults. The following command will create a file named package.json:
npm init
screenshot of package.json file contents after npm init command execution
Here index.js (file name may be different) is the entry point to our application. This is where we're going to put our javascript code, so create an index.js file and put the following code in it:
class mySuperClass {
constructor(name) {
this.name = name;
}
hello() {
return "Hello:" +this.name;
}
}
const mySuperClassInstance = new mySuperClass("Rick");
console.log(mySuperClassInstance.hello());
//Hello Rick
3. While we can install Babel CLI globally, it is best to do it locally, project by project. The following command will add the node_modules directory and modify the package.json file to add Babel dependencies:
npm install -save-dev @babel/core @babel/cli
screenshot of package.json with babel dependencies
4. Add the .babelrc config file to your project root folder and include plugins for ES2015 + transformations.
Note. In Babel, each transformer is a plugin that we can install individually. Each preset is a collection of related plugins. Using presets, we don't need to install and update dozens of plugins ourselves.
Set a preset for all ES6 features (contains a group of plugins):
npm install @babel/preset-env --save-dev
screenshot of package.json with babel preset-env dependency
Edit .babelrc file and add config that includes transforms for ES6.
Write the following code to your .babelrc file:
{
"presets": ["@babel/preset-env"]
}
5. Usage
Note. If you are using Windows 10 PowerShell, be careful with encoding your files as you can get parsing errors when starting Babel. It is desirable that the files are in UTF-8 encoding.
input: index.js
output: out folder (Babel will leave the migrated files here)
Directly by running the following command in the console:
./node_modules/.bin/babel index.js -d out
With an npm script adding the following line to your package.json file:
"build": "babel index.js -d out"
screenshot of package.json file contents after adding build script
Run the following command:
npm run build
In both cases, you get in the out folder a file (or files) transpiled into a ready-to-use browser that doesn't support ES6 class syntax, the code is:
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var mySuperClass = /*#__PURE__*/function () {
function mySuperClass(name) {
_classCallCheck(this, mySuperClass);
this.name = name;
}
_createClass(mySuperClass, [{
key: "hello",
value: function hello() {
return "Hello:" + this.name;
}
}]);
return mySuperClass;
}();
var mySuperClassInstance = new mySuperClass("Rick");
console.log(mySuperClassInstance.hello());
Conclusion
The JavaScript language is constantly changing, and thanks to these tools, we can write code with new syntax and new features that are not yet implemented in all versions of browsers.
I hope you enjoyed this article. I broadcast this and many other useful articles for beginner Frontend developers on the Frontend.school () Telegram channel , where I also prepare useful quizzes to test my knowledge. I draw your attention to the fact that the channel is purely a hobby and a desire to help and does not bring material benefits for me.