This article is part of the Webpack from Zero to Hero series. The next chapters are:

Please follow the blog to see even more quality content published!

Disclaimer: All the points of view and experiences are from me, the author, and it may miss some information because I haven’t worked with all tech stacks of each epoch of my time, but rather with one most common work stack I’ll be using as a default.

Introduction

After a successful Webpack workshop reuniting frontend developers from the Berlin (Germany), Lisboa (Portugal) and Poznań (Poland) OLX offices, and after receiving a good feedback, I got the necessary push to create a series of articles (starting from this one) about bringing an application to life while setting up Webpack in the most simple way possible.

OLX Webpack workshop on Poznań — Thanks to all Berlin, Lisboa and Poznań developers for attending it!

But before going full technical, I wanted to share some history about how we got here. This is important to both new JS developers and to more experienced developers willing to do a “backtracking” on their career and look back at the front-end development tools that have become milestones. Those tools gave us independence and the voice to speak as the real engineers we are.

History

It’s time to go back!

Flashback©: I used to play for hours on my Mega Drive 🎮- (source: Gifer)

JavaScript was always considered a “support” language and was never taken very seriously. Back in 2007, when I started doing software development, I used to work with PHP and JS. We didn’t have the terms backend or frontend then, all of use were just “web developers”. Don’t get me wrong, I don’t have an issue with the term. At that time tech jobs didn’t have so many branches because they were following what we also had at that time - everything together in a single web application.

Since that time, I really enjoyed working with the “holy triad” - HTML/CSS/JS. It was the “tableless” era, jQuery and AJAX golden age, it was a revolution!

“Why do we need to refresh the whole page just to update a small part of this screen?”

The first generation: jQuery FTW

Now REST and let me solve this 😴

Few years passed, the Web Applications were becoming bigger and the backend guys were converting everything to a service. This was the new trend, — you just do Ajax now, you rely on our REST API, no more posting forms or UI on backend. While before I was 40% a backend and 60% a frontend developer, now I was almost full-time JS developer, no more focusing on CodeIgniter, Symfony, Django or Flask.

The first JS frameworks started to appear, proposing to go to SPA (single page applications) and bringing the MVC pattern, something that we were used to see only on backend now also on frontend. I started to work with Backbone JS, but I heard a lot about KnockoutJS too. Together with jQuery UI and Twitter Bootstrap we created several web applications, now much more rich and powerful than before.

Then we started to naturally use the terms frontend and backend, because of this new way to build web applications where we had people working full time on both parts.

The second generation: Backbone JS, jQuery UI, Twitter Bootstrap

OMG there’s so many `<script>` on the page! 😱

👔 — “So many third party styles and scripts, this is out of control! This is blocking the page and our users are always complaining that our app feels too slow!”

The applications where growing… too much! OK we need some way to ship this in a smart way, like requiring it only when necessary, and including something that’s common for backend guys: Continuous Integration!

With this situation, after some research, we found out RequireJS and its nice idea of loading JS in an asynchronous way (AMD — Asynchronous Module Definition), never blocking a page with numerous <script> tags. There was only a single entry point script which required all the other scripts, downloading then through Ajax and parsing them internally, based on the format:

Defining a AMD module using RequireJS

But hey, we needed a way to ship this too, and minify all this stuff that was interconnected but should have been maintained separately, so the old concat and minify would not work for us. That’s when we found GruntJS.

We started to create some scripts with the new kid on the block called Node.js (and now just Node), started to take advantage of LESS inside of Bootstrap and watch for changes on such files.

We were able to do all what we needed with them, but the projects grew and it started to be really painful to run the builds in watch mode, and we were coming back to the monolith days, waiting for the backend to pre-process everything to render the pages.

The third generation: RequireJS, LESS and GruntJS

“Better” frameworks 📐 calls for “better” toolchains! 🚧

Grunt became slow, RequireJS syntax was kinda dirty and Backbone was not enough. Something had to be done.

So came the natural conversion to Gulp which was able to run multiple tasks in an asynchronous way, and way faster than Grunt did. The new new kid on the block was AngularJS, promising a mind blowing way to keep your UI always updated, replicating the models (data) and making you forms data (or any kind of input) being automatically applied on your models. It was the MVVM pattern.

Also, a tool called Browserify came with the promise of module resolution, something we had on Node.js but didn’t have in browsers, and without the nasty syntax AMD had. The syntax was simple: use the “require()” from CommonJS.

The fourth generation: Browserify, Gulp and AngularJS

So, you were talking about performance… 🐢 🐇

It didn’t take long for applications using AngularJS to start suffering from performance issues. Of course, because the tool was born from some designers prototype but then became a framework! To sync up model with the view and vice-versa, it used a heavy algorithm to check for updates on both sides: the infamous Dirty Checking, registering watchers for pieces of data/views, which were prone to grow fast and stay in memory, causing severe memory leaks. And then this guy came kicking at the door:

It came with the idea of one way data flow (as opposed to Angular’s two-way street) and Virtual DOM algorithm, performing way better than Angular. It introduced a new syntax too — one called JSX.

JSX — A a syntax extension to JavaScript

Instead of manually adding polyfills, we used BabelJS to do this job, and since Babel was a transpiler, we were able to input JSX and translate it to JS too. 🎉

Finally, with all these tools we arrived to the bundlers era:

The current generation: BabelJS, Webpack and React

What is a Module Bundler?

Is like a fusion of module resolvers and task managers. It assumes responsibilities of what RequireJS or Browserify did, taking care of modules resolution, but also assumes some responsibilities of task managers like Grunt or Gulp, watching the files and parsing different types of files - other than JavaScript. 💡

What does Webpack do? 📦

Webpack is a module bundler, and currently one of the most famous out there (among others, like Parcel and Rollup). It doesn’t only take care of resolution of modules but, with the help of the loaders, parses different kinds of files and treats them equally as JS modules. We normally use it along with ECMA script imports, but it also gives support to CommonJS require and AMD require/define, and is capable of exporting all of them using the UMD (Universal Module Definition) format.

But can Webpack take care of ALL TASKS? 💥

No, because it doesn’t do 100% of the “task management” work of the tools like Gulp or Grunt. But now we can use simple tools to do the job. In this series we’re going to use npm scripts as it’s a simple solution and covers everything that Webpack don’t.