webpack By Example: Part 4

This article is part of a series (starting with webpack By Example: Part 1) of articles that, through a number of progressively more complicated examples, explores the purpose and functionality of webpack. The examples’ configuration files and source code is available as a GitHub repository.

At this point we have a build process that supports both a development and production work-flow. It supported browser-ready ES5 JavaScript and CSS.

In this article we will explore writing in ES2015 (not supported in the browser) and transpiling it to ES5 in the bundled files.

ES2015

From this point forward, I will be manually building upon the production-ready configuration that was built through the previous articles. At the same time, we use the webpack-cli init command for guidance.

This time, I chose Yes to the Will you be using ES2015 option with the following results:

packages added:

  • babel-core
  • babel-loader
  • babel-preset-es2015

rule added to webpack.config.js

{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['es2015']
}
},

To replicate this configuration we execute the following commands from the command line in the project folder and using an editor add the rule (above) to the rules section of webpack.config.js.

yarn add --dev babel-core
yarn add --dev babel-loader
yarn add --dev babel-preset-es2015

Executing the command ./node_modules/.bin/webpack-dev-server --open from the command line in the project folder will start the development build work flow. Since, I left the source files unchanged we get the same result as before (the cute cat and yellow background) and have not exercised the transpiler (the examples thus-far have not included any ES2015 syntax).

Additionally, because it time consuming always typing in the long commands for development and production builds, we can add the following to the scripts in package.json.

scripts added to package.json

"build": "./node_modules/.bin/webpack -p --env production",
"start": "./node_modules/.bin/webpack-dev-server --open",

and then use either npm run start or yarn start to start development build or npm run build or yarn build for the production build.

babel-polyfill

In the previous example, even though we transpiled the ES2015 code to ES5, the code did not actually have any ES2015 syntax; we correct that here.

src/index.js

require('./index.css');
var cute = require('./cute.jpg');
var rootEl = document.getElementById('root');
var imageEl = document.createElement('img');
imageEl.src = cute;
rootEl.appendChild(imageEl);
// DEMO ES2015
let demo = 'DEMO';
demo = 'Hello ES2015';
window.console.log(demo);
// DEMO BABEL POLYFILL
const promise = Promise.resolve('done');
promise.then(value => {
window.console.log(value);
});

The updated code uses the following ES2015 syntax:

  • let
  • const
  • Promise
  • arrow functions, i.e., () => {}

Running yarn build and inspecting the dist folder we find:

  • main.bundle.js is 869 bytes
  • let, const, and the arrow functions have been reformulated in ES5
  • Promise was left unchanged; bundle still has ES2015 code in it.

relevant section of dist/main.bundle.js

...
var u = "DEMO";
u = "Hello ES2015",
window.console.log(u),
Promise.resolve("done").then(function(e) {
window.console.log(e)
})
...

While the Babel transpiler does convert ES2015 syntax to the equivalent ES5 syntax, it does not provide additional functionality (polyfills), e.g., promises. The solution for promises and similar ES2015 functionality is provided by the package babel-polyfill. To use:

  1. yarn add babel-polyfill
  2. Add require('babel-polyfill'); at the top of index.js.

Running yarn build and inspecting the dist folder we find:

  • main.bundle.js is 85kB (increased due to ES2015 polyfills)
  • As before, let, const, and the arrow functions have been reformulated in ES5
  • Promise is implemented in the bundle.

import / export

Up until now we have been using the require function and module.exports variable to import / export functionality. With ES2015 we replace it with equivalent import and export syntax.

src/index.js

note: Left in commented out the old require statements for comparison.

/*
require('babel-polyfill');
require('./index.css');
var cute = require('./cute.jpg');
*/
import 'babel-polyfill';
import './index.css';
import cute from './cute.jpg';
// DEMO EXPORT
import secondary from './secondary';
var rootEl = document.getElementById('root');
var imageEl = document.createElement('img');
imageEl.src = cute;
rootEl.appendChild(imageEl);
// DEMO EXPORT
secondary();

src/secondary.js

note: Left in commented out the old require statements for comparison. Also used ES2015 arrow function syntax.

/*
module.exports = function() {
window.console.log('hello secondary');
};
*/
export default () => {
window.console.log('hello secondary');
};

The Next Part

In the next part, webpack By Example: Part 5 , we will explore CSS transpiling, e.g, SASS.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.