Getting started with webpack
As web applications have gotten more complex, so has the technologies used to build them. Magic can be good when all works as intended, but it can be frustrating when they don’t. This was how I felt about webpack until I watched the Webpack Fundamentals course on Frontend Masters. I cannot recommend the course enough if you are able to get your hands on it. Lets just go over stuff I think is worth knowing to become productive with webpack and debug basic issues while using it.
Should you use webpack?
It depends, but I personally think if you write highly structured javascript with your code organized into modules and/or across various files and directories, webpack can help by pulling them together into one script (or more if you like) that you can include in your html - this is what is known as bundling. The benefit being that you don’t have to manage adding script tags to your html file and figure out what order to add them in to make stuff work.
You can essentially go from something like
<html lang="en">
...
<body>
...
<script src="js/tracker-util.js"> <!--Shared so must come first! -->
<script src="js/counter.js">
<script src="js/accordion.js">
<script src="js/api.js">
</body>
</html>
to
<html lang="en">
...
<body>
...
<script src="js/bundle.js">
</body>
</html>
and no matter how many more modules you create in the future there is no presure to add more than just bundle.js
in your webpage.
There are a lot of other benefits I won’t cover but see the official docs for more. Lets get started on some basics .
Useful terms
-
Loaders: Webpack understands how to work with JavaScript and json files out of the box. If you need to pull any other file types into a format that webpack can understand, you need a loader.
-
Plugins: Plugins are similar to loaders but are typically used for more robust processing. A good example: while
css-loader
will transform your styles into a webpack friendly format, themini-css-extract-plugin
will take it a step further and enable you to extract your styles into a stand alone css file (likestyles.css
) that you can then link to on your webpage. -
Entry: The is the starting point for webpack when determining what goes into your bundle. It will figure out a dependency graph starting from your entry file and pull imported items into the resulting bundle (Known as the output file).
With these useful terms in mind, when I want to do something non JavaScript/json in webpack, my first thought is Is there a webpack loader or plugin for this? and my next is how do I make use of it. Understanding that the bulk of what I am trying to do is get stuff into webpack land and reliably generate bundles has made setting up and debugging webpack issues a lot easier for me.
Our first webpack file
With the somewhat lengthy intro out of the way, lets see if we can setup a webpack file that will let us create an accordion and a counter. Yes, its contrived but the prize here is not what we are building, its how we use webpack to do it.
The initial project state can be found here on GitHub. We will progress through relevant branches as we continue.
Project summary:
src/tracker.js
is a utility that tracks usages for analyticssrc/accordion.js
andsrc/counter.js
respectively contain the logic for an accordion and a counter. They both import and make use of the tracker utility.src/index.js
is our entry file and pulls in the accordion and counter files for usage on the webpage.- Finally, the
dist
directory contains anindex.html
page which inludes a script link to amain.js
file (our bundle - which will be generated by webpack).
Downloading the project and running webpack
after installing the dependencies (via npm install
) should result in a new main.js
file being added to the dist
directory.
What has happened here?
The webpack
command executes the webpack CLI in your project folder with some reasonable defaults, some of which are:
- Your entry file is located at
src/index.js
- You want the output in a
dist/main.js
file —> this is your resulting bundle (Which we already included in ourindex.html
)
Opening index.html
in your browser should result in the content and console logs resembling the screen shot below:
What if we wanted to take it a step further? Our page is looking pretty bland. Lets add some style sheets to make things look nice.
Summary of changes:
-
Reorganized the scripts into separate directories
src/accordion.js
is nowsrc/accordion/accordion.js
src/counter.js
is nowsrc/counter/counter.js
src/tracker.js
is nowsrc/utils/tracker.js
-
Added style sheets and imported them into the scripts.
- added a new stylesheet
src/accordion/accordion.css
and imported it intosrc/accordion/accordion.js
- added a new stylesheet
src/counter/counter.css
and imported it intosrc/counter/counter.js
- added a new stylesheet
The updates can be found in the broken-importing-styles-no-loader branch.
Running webpack
to get a new bundle now should give the following error message:
This is webpack telling us that it cannot handle the css files and suggesting that we may need a loader to do it for us.
The fix:
In order to get the styles working, we need to setup loaders for the css. We will rely on css-loader
(for parsing the css file) and style-loader
(for injecting the resulting <style>
tags into our html page).
- First run
npm install --save-dev css-loader style-loader
to add the npm packages - then create a
webpack.config.js
file at the root of your project with the following:
//webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
};
We have now stepped it up a little by using this webpack configuration file. It gives us more flexibility in configuring how webpack should work in our project. Specifically, we have added a rule to the module.rules
array config property that says the CLI should use style-loader
and css-loader
when it encounters a file ending in .css
.
Running webpack
now should now compile the project successfully the the following result when we refresh the page in the browser.
Maybe not the prettiest web app ever, but we can certainly make more changes using all sorts of fancy code and webpack loaders to get it how we want it to be.
The final working code can be found in the working-importing-styles-with-loaders branch.