Practicing ES6 with Babel and Webpack
By: Aakash Mallik
Tags: JavaScript, ES6, Programming, Practice, Coding

Webpack

Webpack is basically a tool that is used by web developers to create code bundles that are bug resistant. The formal genre of this tool is ‘Task Runner’. You give it code, you give it instructions about how to process your code and on the execution of a single terminal command, it spits out a code bundle. A classic use case of this is given on the official docs of Webpack right here.

Note: If you have ever come across grunt or gulp, this is somewhat a similar tool. This tool has actually made the gulp/grunt go obsolete.

Once you are done following the simple Getting started section in the docs, you will end up with something like this.

// webpack.config.js const path = require( 'path' ); module.exports = { entry:'./src/index.js', output:{ filename:'bundle.js', path: path.resolve( __dirname,'dist' ) } };

Note: Out of the box, Webpack will only understand the import and export keywords from ES6. Anything more than that will be left unchanged. Webpack basically takes the help of these import/export statements to figure out how to create the bundle and in which order the code should be considered for bundling.

I have put two files in my src folder.

//index.js var utils = require('./utils'); message = utils.joinMessage('I think this is cool', 'but this is hot as well'); console.log(message);

and

// utils.js const joinMessage = function(firstText, secondText) { return '' + firstText + ' ' + secondText; }; module.exports = { joinMessage: joinMessage };

You can surely use import instead of require() and export instead of module.exports in the above code.

Babel with Webpack ( babel-loader module )

An interpreter? A compiler? No, it’s a transpiler. So what in God’s name is a transpiler? Well, it talks one version of a language and converts into another version of the same language with minor/major tweaks for best performance. In our case, ES6 is getting converted to platform friendly ES5 code. And we will use Babel with our handy task runner Webpack to accomplish this.

To make the above setup work to transpile your ES6 code you need to use a loader specifically the babel-loader. Loaders are basically file preprocessors. This will extend the functionality of Webpack to bundle not just JS, but absolutely anything. This page talks about the loaders in details. Let’s use the loader used in the docs for ES6, given here.

If we look carefully in the npm install statement here.

npm install babel-loader babel-core babel-preset-env webpack

You will notice something interesting. Other than the babel-loader, the other two imports — babel-preset-env, babel-core; are part of the babel module which is not part of Webpack. So you can quickly head down to Babel docs to see that Babel could be used even without Webpack; but then you would have to use the Babel-cli and write another ‘.babelrc’ file. We would take the hassle free way out. We will use it with Webpack.

Let’s see how out webpack.config.js should look now. Then we’ll break it down one step at a time.

const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['babel-preset-env'].map(require.resolve), }, }, }, ], }, };

Note: The docs will suggest you to use

presets: ['@babel/preset-env'],

but that brings up some issues so use this one to let nodeJS find preset-env

presets: ['babel-preset-env'].map(require.resolve),

Now let us break it down.

What have added the module attribute to our old object. This object will be used when we wish to use loaders and it’s options. test will tell Webpack which files to look for. In our case it is a regular expression saying ‘every file that ends with a .js’. The exclude attribute tell which folders to leave out. Obviously you would not want Webpack to touch the third-party files in your node_modules folder for transpiling. In the options attribute, you will mention any presets that you would like to use. Se, we are trying to convert from ES6 to ES5, hence the babel-preset-env will be used. These is a separate preset for JSX and so on… And that’s it; we are good to go.

Before we test our config file, let’s write some ES6 code to test this on.

//main.js import joinMessage from './utils'; const message = joinMessage('I think this is cool', 'but this is hot as well'); console.log(message);

and

//utils.js

const joinMessage = (firstText, secondText) => { return `${firstText} ${secondText}`; }; export default joinMessage;

Run this in the root of your project.

npx webpack --config='./webpack.config.js'

If everything goes well, you should see a screen without error text. And now you can run your bundle.js without any problem which is basically the transpiled version of your ES6 code.

Check it with this command

node ./dist/bundle.js

Bingo!! It works like a charm…