Just the mere mention of
Webpack starts to build those feelings of semi-dread but also a lot of curiosity. What
is Webpack really? Should I bother? Is it just a fad?
There’s a lot of opinion just around those questions, so instead of me just standing on a soapbox, it might be a lot more useful for me to present Webpack and THEN maybe a bit of soapboxing, I mean c’mon it IS the Internet!
To help illustrate where we might take advantage of Webpack, we’re going to create a very small one page type of project. Think of something just smaller than the standard ToDo application.
[…] is more like a big ball of wibbly-wobbly, timey-wimey … stuff.
- the TimeLord either talking about Time… or Webpack
first things first - initialize the project
You can grab the source code to this guide HERE.
Let’s get a new project going to set everything up. Enter your favorite project home and create a new directory for playing around with Webpack.
npm install webpack webpack-dev-server html-webpack-plugin --save-dev
After those packages finish installing themselves, we can setup the project structure we’re going to reference:
setup and test webpack configuration
All those nasty and mean webpack jokes by internet people aside, one of the first things I tackle in a project is to solidify the “build” process tooling. While it can sometimes feel like a task that should come just a few steps later into a project, my intention is to setup a development environment where I can feel productive once I start writing actual code.
During the initial excitement of a project kickoff, my brain is jumping from potential challenges and things to tackle within the code.
However I’ve learned this is when my productivity level isn’t very optimal.
If you’re slightly unfamiliar with Webpack (not a problem), it is a popular front-end build and pipeline tool. If
you’ve used task based tools such as Grunt or Gulp, then someone new to Webpack it is roughly similar. Grunt has
Gruntfile.js, while Gulp has its
gulpfile.js. So to is the relationship between
webpack.config.js and Webpack.
The Webpack documentation has been improving at a fantastic pace, so if my explanations don’t make sense, then it shouldn’t be too much of a time sink hunting down where your issue is.
Here’s a section of the documentation on Webpack configuration
output.path - Webpack has a concept of plugins within its pipeline which are used to greatly enhance and apply transformations
to your application code. We won’t go too deep into that just yet. Just remember that the output.path should JUST
contain the folder ROOT path of where you want the finished bundle. All of Webpack’s transformation plugins will
reference the same
output.filename - This is the specific filename of our final application bundle. If you want it within a sub-folder
output.path, then you should be doing that here in the
plugins - this is an Array of Webpack plugins that you can just drop right into your pipepline. We are most
interested right now with
HtmlWebpackPlugin which will take a file as the
template input, then automatically
inject the necessary
<script> markup along with your
output.filename. If that explanation doesn’t
click, then just inspect the resulting
index.html when the build completes. It will make sense.
devServer - This object is just some settings for applying to
webpack-dev-server. While running, the dev-server
keeps your entire application in memory, so while it’s using your Webpack configuration settings, nothing is being
written to disk.
contentBase defines the folder you want web accessible.
port just gives you the freedom to
define your own port.
open will open your favorite web browser for you to the given
updating the start script in package.json
Just for your own convenience during local testing, let’s stuff all of our
webpack-dev-server stuff into a much
Now to run everything locally, just type
npm start in your terminal. You can keep this running in the background
while you make source code changes, and Webpack will manage refreshing the browser when necessary.
adding babel support
Okay we’re not quite done with Webpack configuration. Rather then throw a giant blob at you, which will likely cause your eyes to just glaze over, I thought it’d be an easier digest if things were broken into chunks (kinda like Webpack itself! get it? get it?)
Luckily there’s a Webpack loader for this purpose specifically, called babel-loader.
Just install it via NPM using:
npm install babel-core babel-loader babel-preset-env --save-dev
adding a module section to webpack.config.js
Unlike plugins which has access to pretty much everything related to your final build (in memory), a loader is more of a pre-processing type of tool for Webpack. It might not be too helpful to go into too much detail around loaders, but they are normally used by Webpack during the building phase of your codebase.
You will typically provide Webpack with a RegEx to define which loader to apply to which type of file.
(Just keep reading, as you work through this, I’m hoping it’ll make sense and click).
Let’s update our
webpack.config.js to accomodate Babel.
Other loaders will make its way into our configuration before we’re through. The
module object contains a
Array which is where we define what kind of
loader to apply to which filetype.
rules.test we have defined a RegEx pattern that specifies that this loader is concerned about files with an
extension of either
.jsx. Once Webpack finds a file that satisfies this criteria, it will look in the
rules.use Object for settings on how to handle it.
In this particular case, we’re telling Webpack to use the
babel-loader when it finds files that pass the test. The
options aren’t really important, just that we want to use the
env preset for Babel (which is why we
babel-preset-env package). Other presets exist for toolkits like React or when working with es2015,
but for now env is enough.
our starting index.tmpl
Before putting down some explanations on Webpack and HTML templates, let’s go ahead and look at our
This is quite a basic index template, but believe it or not, depending on your project – it might be all that’s required.
One of the more common Webpack plugins available is html-webpack-plugin. I’ve already mentioned that plugins are (for the most part) transformers. They work (in memory) with the pieces of your entire application, and help transform from one state or style into another one.
Back to this specific plugin. Our main
index.html currently lives in
./src as a template,
you can name this file whatever you want, I just wanted a visual cue that it’s a template.
Notice that we don’t need to put any of our
script references in there, because we’re handing over control of everything
over to Webpack.
As Webpack processes your
entry source code, it will then load up the
html-webpack-plugin and the
template file and combine everything together. The end result will be your
./public/index.html file along with
script references to your newly generated application bundle!
Adding support for SASS (optional)
Okay we are on a Webpack roll here. Most web sites or applications rely on some kind of use of CSS. I don’t want to go through the advantages of using SASS right here, but I’m going to assume for the moment that you want it in your projects as much as I do.
npm install node-sass sass-loader css-loader style-loader --save-dev
As you can probably guess given this dependency list, we are using loaders to intake and transform our SASS to CSS.
time to update your webpack.config.js
reference your SASS from your JS module
Again, you might now notice that the
./src/index.tmpl template makes no reference to our application CSS. No, I didn’t
The same way that Webpack will create a bundle for your script references during a build, it can do the same thing for your SASS.
Right at the top of your
entry file, just make a reference to the SASS file.
That’s it we are done with the basics of Webpack
While maybe it felt like a “long” process, this is the kind of thing that you really only need to setup and configure once. Once you put in the work of setting up your own Webpack configuration, you can just about carry it from project to project.
However we’ve only just covered the bare basics of Webpack. There’s so much left to explore and enjoy. There’s topics like JSON loading, image optimization, code-splitting and so much more.