One question I get a lot from people who are just starting out with web development is along the lines of "why is there all this extra overhead for a build process?", and I remember when I was starting out and wondered the exact same thing. My first website loaded Bootstrap's CSS and JS onto every page, and had page-specific styles in a
style tag at the top. Any scripts I had were inside a
script tag at the bottom of the page. I looked at things like Grunt, Bower, and npm and wondered why people were making it so darn complicated. After all, why is it so difficult to load a CSS file and a maybe a couple scripts into a page?
If this resonates with you right now, then hopefully this post will shed some light on why we use build tools and the benefits they can provide.
When learning web development - especially in a school environment, I've found - the setup of your web pages is generally quite simple. You probably have an
index.html in the root of your project. You might even have multiple pages that you can link to. You've likely got a
styles directory, and a
scripts directory where you put your CSS and JS files, accordingly. So maybe you've got something that looks like this, for a basic site:
1. 2├── about.html 3├── contact.html 4├── index.html 5├── scripts 6│ └── index.js 7└── styles 8 └── main.css
Then, in your HTML files, you might have something like this:
1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <title>My Awesome Web Page</title> 6 <link rel="stylesheet" href="/styles/main.css"> 7 </head> 8 9 <body> 10 <aside> 11 <nav> 12 <ul> 13 <li><a href="/">Home</a></li> 14 <li><a href="/about.html">About</a></li> 15 <li><a href="/contact.html">Contact</a></li> 16 </ul> 17 </nav> 18 </aside> 19 20 <main> 21 <h1>Hello World!</h1> 22 </main> 23 24 25 <script src="/scripts/index.js"></script> 26 </body> 27</html>
No big deal. This is pretty easy to manage manually, so if this is as big as your site ever gets, congrats! You honestly probably don't need a build process.
However, anyone who has done this for long enough can tell you that very rarely, in an active project, are you ever "done". There are always more features, more requests, more content (and that's not always a bad thing).
1. 2├── index.html 3├── pages 4│ ├── about.html 5│ ├── contact.html 6│ ├── docs.html 7│ └── faq.html 8├── scripts 9│ ├── analytics.js 10│ ├── carousel.js 11│ ├── dropdown-menu.js 12│ ├── index.js 13│ └── lazy-load.js 14├── styles 15│ ├── footer.css 16│ ├── bootstrap.css 17│ ├── landing.css 18│ ├── main.css 19│ └── normalize.css 20└── images 21 ├── kitten1.jpg 22 ├── kitten2.jpg 23 ├── kitten3.jpg 24 ├── kitten4.jpg 25 └── kitten5.jpg
index.html might look like this now:
1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <title>My Awesome Web Page</title> 6 <link rel="stylesheet" href="/styles/normalize.css"> 7 <link rel="stylesheet" href="/styles/bootstrap.css"> 8 <link rel="stylesheet" href="/styles/landing.css"> 9 <link rel="stylesheet" href="/styles/footer.css"> 10 <link rel="stylesheet" href="/styles/main.css"> 11 </head> 12 13 <body> 14 <aside> 15 <nav> 16 <ul id="dropdown-menu"> 17 <li><a href="/">Home</a></li> 18 <li><a href="/pages/about.html">About</a></li> 19 <li><a href="/pages/contact.html">Contact</a></li> 20 <li><a href="/pages/docs.html">Docs</a></li> 21 <li><a href="/pages/faq.html">FAQ</a></li> 22 </ul> 23 </nav> 24 </aside> 25 26 <main> 27 <h1>Hello World!</h1> 28 29 <section class="image-carousel"> 30 <img src="/images/kitten1.jpg"> 31 <img src="/images/kitten2.jpg"> 32 <img src="/images/kitten3.jpg"> 33 <img src="/images/kitten4.jpg"> 34 <img src="/images/kitten5.jpg"> 35 </section> 36 </main> 37 38 <script src="/scripts/index.js"></script> 39 <script src="/scripts/analytics.js"></script> 40 <script src="/scripts/carousel.js"></script> 41 <script src="/scripts/dropdown-menu.js"></script> 42 <script src="/scripts/lazy-load.js"></script> 43 </body> 44</html>
Okay, that's starting to get to be quite a few files to manage. It's still nothing crazy, but you are going to have to keep these in sync across every page in your site.
In addition to the overhead involved there, each separate file requested (CSS, JS, image) is one network call to get the data, and that slows down your page load. On a poor connection, each extra HTTP call is going to cost even more in terms of performance and load times.
Build tools - things like Grunt, Gulp, and Webpack - can automate a lot of processes that make your site better and are super repetitive. Let's take a look at a few of the things you can accomplish, and hopefully you'll start to understand why we use these tools so frequently.
One of the quickest wins you can get from build tooling is that you can compile all of your scripts and styles into one file, so you only have to have a single
link tag. The file size will be larger, but typically the extra size is well worth making only one or two HTTP calls.
Images are almost always the largest files on your site, so any way you can optimize them to reduce the size without sacrificing too much of the quality is a big win. There are plenty of tools out there to do this. If you know the max-width of the element the image will be in, you can also have the images be resized. For instance, if you have a high res image that's 6000x6000 pixels, but your content is inside a container that has a max-width of 1000px, the browser is still downloading a 6000px wide image (massive file size) and shrinking it down to fit inside of 1000px. Instead, consider resizing it to 1000px and dropping the quality down from 100% to something in the 70-80% range, and you'll notice a HUGE reduction in file size, making the images load significantly faster.
Automated tests can save you hours of hassle trying to troubleshoot a production issue. Having a good suite of automated tests is important, so you should run them. Build tools can ensure that your tests get run before your code gets too far down the line with bugs in it.
Similarly to tests, linters like ESLint and JSHint can find issues in your code and alert you that something isn't right before you ship it. Running your code through a linter is a common task that build tools can do.
It's a first-world problem for sure, but it's frustrating to save your code, wait for it to compile, and then switch over to the browser and reload it. Wouldn't it be nice if there was a way something could watch your filesystem for changes, recompile your code when there is, and then refresh your browser window when it's ready, so you don't have to sit there mashing
cmd-R? Yeah... build tools can do that for you.
While this isn't an extensive dive into how to set up your build process, I hope you gained a bit of an understanding on why everyone actually uses these tools. At first, it can seem like it adds a lot of complexity to a project, but when you realize all of the things that it does for you, the time it saves you is exponential. Can you imagine having to do all of those tasks manually, many times per day? As the complexity of our sites and applications grows, we rely on build tools to help us maintain a consistent pipeline for getting our code out to the world so people can use it.