Webpack is primarily a bundler, and as such you can also use it to bundle just about any resource or asset you care to think of. In this journal we will be talking about how you can bundle project using Webpack.
We will be working on to configure Webpack, then use it to create a minified bundle for a simple static site with a handful of assets. But before we start the configuring part you need to install the Webpack on your dev machine. If you have not done so, then I will suggest you go through the following journal “How to install Webpack For Module Bundling” first.
You may be tempted to ask the question that why we should be using Webpack to bundle the static site. The main primary reason for doing the same is to minimize the HTTP requests that the site will be making to the servers. By these HTTP requests, I mean to say the requests that the site will be making to jQuery, fonts, plugins, and some Javascript of your own. As soon as the network requests for these add up, the page can become sluggish and response time increases to render the page. However, if we bundle all of the above requests, then this problem disappears.
Another feature of using Webpack is that it also makes it easy to minify your code thus reducing the network request size.
In this journal, I will be demonstrating on how we can use Webpack to bundle the package, minify the code base, and also will have a look at the process to transpile ES6 code to ES5 code. By the word transpile, I mean to state that we can write JavaScript using the latest, most up-to-date syntax (this might not be fully supported in all the browsers), then serve the browsers ES5 code that runs almost everywhere.
#Getting Started
To get started with the Webpack, you need to be sure that you have Node.js
and npm
installed on your machine. And also the most important part, Webpack.
npm install webpack --save-dev
npm install webpack –save-dev
The above code helps in installing the Webpack locally for your project and add it as devDependency
on your package.json file.
"devDependencies": { "webpack": "^3.2.0" }
Next step is to create the dist
folder in the root folder of the project.
mkdir dist
#Automating the Setup Process
Let’s create an npm script
in the package.json
file which we will use to run and build the final package.
"scripts": { ... "build": "webpack" }
Now to use this build script we will be requiring one important file for Webpack. This file is called as webpack.config.js
and it will reside in the root folder of the project.
This file is the main configuration file for bundling our project files and generating the final output file. These files will be passed in as arguments to this configuration file.
Create the webpack.config.js file.
touch webpack.config.js
and add the following lines of code to it.
module.exports = { entry: './src/js/app.js', output: { path: __dirname + '/dist', filename: 'bundle.js' }, module: { loaders: [ { test: /\.css$/, loaders: [ 'style-loader', 'css-loader' ] }, { test: /\.(svg|gif|png|eot|woff|ttf)$/, loaders: [ 'url-loader' ] } ] } }
Now let’s understand the components defined in this file.
#entry:
This is the main entry point of the project which will be having a reference to all the file components that we require to bundle out in the package. The components of this file for quick reference is specified below:
// CSS require('slick-carousel/slick/slick.css') require('slick-carousel/slick/slick-theme.css') require('lightbox2/dist/css/lightbox.min.css') require('../css/main.css'); // JS window.$ = require('jquery'); window.slick = require('slick-carousel'); window.lightbox = require('lightbox2'); require('./main.js')
In the above code snippet, the first few lines contain the reference to all the CSS files whether local to the project or if you are using some third party frameworks. Then the next block of JS specifying all the javascript reference assuming you have them installed on your machine using npm for all the third party javascript except for the one which is local to your project.
#output:
This contains the folder location and the file name which will become the final output of our packaged bundle.
#module:
Although in its standard configuration Webpack can only deal with Javascript, we can use something known as loaders
to have it bundle our CSS, too.
Loaders are transformations that are applied on the source code of a module. They allow you to pre-process files as you
import
or “load” them. Thus, loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language (like TypeScript) to JavaScript, or inline images as data URLs. Loaders even allow you to do things likeimport
CSS files directly from your JavaScript modules!According to Webpack docs
As in the above-mentioned code snippets, you have seen that we have specified two loaders: css-loader and style-loader. Of the two, css-loader transforms CSS to a JavaScript module and style-loader injects the CSS, that is exported by the JavaScript module, into a <style> tag at runtime. Let’s install both:
npm install --save-dev css-loader npm install --save-dev style-loader
Besides these two loaders, have you noticed that I have used another loader url-loader. This loader helps in converting assets like fonts and images into Data URLs, which are then added to the bundle. For the url-loader, we have provided a valid RegEx expression which will check for images and fonts files used in our project.
Once you are done with these files, all you have to do is run the following command on the terminal from your project root.
npm run build
The above command will check that we are using the build script to run our package and we have specified Webpack to it. So it will give control to the Webpack which in turn will use the webpack.config.js
file and build the final bundle.js
file for us.
#How to use this bundle.js file in your HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DJ - Bundling the Package from Webpack</title>
</head>
<body>
. . .
<script src="dist/bundle.js"></script>
</body>
</html>
#Finishing Touches
We are almost done bundling our package, but there are some more couple of things that we can improve upon in our package.
:Handling the Flash of Unstyled Content
Did you happen to notice that whenever the page is loaded there is the flash of unstyled content. This can be fixed by taking advantage of the blocking nature of <script> tags and moving the include to the top of the file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DJ - Bundling the Package from Webpack</title>
<script src="dist/bundle.js"></script>
</head>
<body>
</body>
</html>
:Minify the Bundle
We can also run Webpack with a p
flag (short for production) and have it minify everything for us
In package.json
:
"scripts": { ... "build": "webpack -p" },
In webpack.config.js
:
module.exports = { entry: './src/js/app.js', output: { path: __dirname + '/dist', filename: 'bundle.min.js' }, module: { loaders: [ { test: /\.css$/, loaders: [ 'style-loader', 'css-loader' ] }, { test: /\.(svg|gif|png|eot|woff|ttf)$/, loaders: [ 'url-loader' ] } ] } }
The reference of this bundle.js
in the HTML files will get replaced by bundle.min.js
.
:Transpile ES6 to ES5
You could also install the babel-loader and have Webpack run JavaScript files through that, thus transpiling ES6 to ES5.
npm install babel-core babel-loader babel-preset-es2015 --save-dev
In webpack.config.js
:
{ test: /\.js$/, loader: 'babel-loader?presets[]=es2015' },
So there you have it!
In this journal, I have tried to demonstrate how we can use Webpack to bundle a simple static site — a process that reduces the number of HTTP requests made, thereby making the site potentially snappier and more responsive. I also tried to show how to have Webpack minify the resultant bundle, thus considerably reducing the file size, as well as transpile ES6 using the babel-loader.
Even if this strategy isn’t for everyone, hopefully, you have gained an insight into what Webpack does and how it does it.
For those that wish to explore Webpack further, I recommend A Beginner’s Guide to Webpack 2 and Module Bundling, which goes a little more in-depth.
Some kind soul finally thought to make a few options specifically for static websites! In addition to markdown docs, Ink for all gives you the the ability to export in a format compatible with Hugo and Jekyll. Anybody else heard of it?