Demystifying and Setting up .babelrc
Hi Folks! Lately, I have been inquisitive about what’s the fuss about this React’s ecosystem. Eric Elliott said:
First, software ate the world, the web ate software, and JavaScript ate the web. In 2018, React is eating JavaScript.
Rather React is eating Jquery. :P
Anyway, I was setting up a React project from scratch, one of the daunting task I came across was writing .babelrc file. I didn’t want to do the xeroxing work out here from some blog or post.
This post will help in understanding and setting up Babel in webpack and npm environment.
Babel is a tool for transpiling (compiling) ES6/ES7 code to ECMAScript 5 code, which can be used today in any modern browser. Furthermore, Babel has extensions for transpiling JSX for React and Flow syntax for static type checking.
Hoping that babel is already installed, let’s move on with installing babel-loader
, a transformer for .jsx files in your webpack, as a devDependency in package.json.
npm install babel-loader --save-dev
In webpack.config.js, you’ll need to add the babel-loader to the list of modules:
module: {
rules: [
{
test: /\.jsx$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
},
You can pass options to the loader by using the options property:
module: {
rules: [
{
test: /\.jsx$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
options: {
presets: ['@babel/preset-env'],
plugins: [require('@babel/plugin-proposal-object-rest- spread')]
}
}
}
]
}
This loader also supports the other loader-specific options:
- cacheDirectory
- cacheIdentifier
- .babelrc
Read indepth here. It is recommended to use the .babelrc
approach, which is a configuration file for Babel.
In Babel, a preset is a set of plugins used to support particular language features.
Let’s start off by creating the file and adding the code:
{
"presets": []
}
Now, let’s start telling Babel to transpile ES6/es2015 code to ES5. Initially babel came up with es2015 preset, which allows babel to transpile all the features of es2015 if present in the file. Then came latest preset, which is deprecated now since it is same as the env preset. The env preset, contains all yearly presets so users won’t need to specify each one individually. It currently includes es2017, es2016, es2015. Babel documentation says:
If you want to stay up to date, use the `env` preset for es6
Let’s install it:
npm install babel-preset-env --save-dev
Next, Babel needs to transpile JSX into createElement calls. Let’s install react preset for the same:
npm install babel-preset-react --save-dev
Let’s add the two presets to .babelrc:
{
"presets": ["env", "react"]
}
Great, we are good to go now. See the magic of Babel yourself. ;)
From now we will be talking about advanced Babel configurations.
The Babel preset contains only ES6 feature. JavaScript has some proposals for new features that are not yet finalised. They are separated into 5 states (0 to 4). As proposals gain more traction and are more likely to be accepted into the standard they proceed through the various stages, finally being accepted into the standard at stage 4.
In Babel, these changes are bundled in 4 different presets:
babel-preset-stage-0
babel-preset-stage-1
babel-preset-stage-2
babel-preset-stage-3
There is no babel-preset-stage-4
as it’s simply babel-preset-es2015
.
Each of these presets requires the later preset. For example babel-preset-stage-1
requires babel-preset-stage-2
and babel-preset-stage-3
.
Simply install the stage you want to use:
npm install babel-preset-stage-0 --save-dev
Then add it to .babelrc:
{
"presets": ["env", "react", "stage-0"]
}
Babel warns that anything pre
stage-3
should be used with caution.
Some presets also has options to configure. More on it Read this.
For example, if you want to target only Chrome 52 and disable transformation of ES6 module syntax to another module type:
{
"presets": [
["env", {
"targets": {
"chrome": 52
},
"modules": false
}],
"react"
]
}
Adding plugins to .babelrc
Babel presets are just collections of pre-configured plugins. You can manually add plugins if you want to do something different.
For example: Let’s add transform-class-properties plugin. This plugin transforms es2015 static class properties as well as properties declared with the es2016 property initializer syntax.
Below is an example from Babel documentation , a class with four class properties which will be transformed:
class Bork { //Property initializer syntax
instanceProperty = "bork"; boundFunction = () => {
return this.instanceProperty;
} //Static class properties
static staticProperty = "babelIsCool"; static staticFunction = function() {
return Bork.staticProperty;
}
}let myBork = new Bork;
//Property initializers are not on the prototype.
console.log(myBork.__proto__.boundFunction); // > undefined
//Bound functions are bound to the class instance.
console.log(myBork.boundFunction.call(undefined)); // > "bork"
//Static function exists on the class.
console.log(Bork.staticFunction()); // > "babelIsCool"
Let’s install it:
npm install babel-plugin-transform-class-properties --save-dev
And configure it:
{
"presets": [
"env",
"react"
],
"plugins": [
"transform-class-properties"
],
}
Babel based on environment
Babel has plugins that can help you in the development process, as plugins for optimising code for production. You can configure which plugins to load, based on the environment you are:
{
"presets": ["env", "react"],
"env": {
"development": {
"plugins": [...]
},
"production": {
"plugins": [...]
}
}
}
The current environment will use process.env.BABEL_ENV
. If BABEL_ENV
is not present, it will use process.env.NODE_ENV
. If NODE_ENV
is not available too, it will default to development
.
babel-polyfill
babel-polyfill
will emulate a full ES6 environment. For example, without the polyfill, the following code:
function allAdd() {
return Array.from(arguments).map((num) => num + 2);
}
will be transpiled to:
function allAdd() {
return Array.from(argument).map(function (num) {
return num + 2;
});
}
This code will not work everywhere, because Array.from
in not supported by every browser:
Uncaught TypeError: Array.from is not a function
To solve this problem we need to use a polyfill. A polyfill is a piece of code, that replicate the native API that does not exist in the current runtime. Babel uses core-js as it’s polyfill and regenerator for its generators and async functions.
To include the Babel polyfill, we need to install it:
npm install babel-polyfill --save-dev
Then, simply include the polyfill at the top of any file that requires it:
import 'babel-polyfill';
Conclusion
Since javascript is burgeoning and developing, new standards are developed at a gained momentum. Babel and its surrounding ecosystem is playing an essential role for today’s modern web applications and support for older browsers. With the provided information above, you should be ready to start using the latest JavaScript specs and accompanied technologies (JSX, ES6, etc.). Babel is going to stay here for long so…. Code on!
If you have found this helpful please hit that 👏 button.
And yes Happy-go-lucky!!!!! :D