Why We Switched to webpack

Spencer Elliott
Aug 29, 2016 · 5 min read
Image for post
Image for post

This is the first of a two-part series on why and how we switched our JavaScript bundling system from an ad hoc system of Grunt tasks and PHP, to a declarative webpack configuration. This post will cover the “why” we did it — Stay tuned for a post that covers the “how”!

Hi! I’m Spencer, a Computer Science student at the University of Toronto. This was an initiative that I kicked off during my internship while working with the event app team at EventMobi.

Until recently, EventMobi’s primary event app codebase had used an ad hoc system of Grunt tasks and PHP to bundle JavaScript for the browser:

This build system had served us well enough, but we eventually ran up against some pain points which could be addressed by using a module bundler like webpack:

1. Resolving dependencies was tedious

Scripts had to be collected in a specific order, otherwise dependencies would be out-of-order: first load jQuery, then load AngularJS, then load AngularJS plugins, etc.

Image for post
Image for post
Managing dependencies with <script> tags

With a module bundler, dependencies are imported using CommonJS `require` statements in the file where they are used, and combined into one JS bundle. So dependencies are guaranteed to be available: no need to render many `<script>` tags in a specific order.

Image for post
Image for post
Managing dependencies with CommonJS modules

2. Hard to use npm packages

Importing packages from npm required us to manually create a UMD bundle if one wasn’t available. Want to use ng-redux? Create a UMD bundle and add it the the list of vendor scripts. Want to use left-pad? Create a UMD bundle.

In Node.js it’s common, and arguably just good design to publish and consume tiny modules from npm like left-pad. But the overhead of creating and managing UMD bundles meant it was often easier to ‘reinvent the wheel’ by re-implementing common functionality than use an npm package.
Oh, and what about when two npm packages share a common dependency? There’s no simple way to share that common dependency between the two UMD bundles; that dependency is now duplicated in each bundle, wasting valuable bytes.

With a module bundler, npm packages can be used with a simple

npm install <name>

and

require('<name>');

No need to create UMD bundles. And if two npm packages share a common dependency, both will share the same code without duplication.

3. Poor dev-prod parity

Scripts loaded during development were sometimes different from scripts loaded in production, since the PHP `<script>`-rendering behaviour for development was separate from the Grunt script concatenation behaviour for production. This meant that sometimes our development build would work, but the production build would fail due to a missing script. In other words, poor dev-prod parity.

With a module bundler, in both development and production, a single JS bundle and a single CSS bundle are created, so there is no disparity between the two environments in how many `<script>`s are rendered.


The above presented us many challenges to solve, and as we started to look into potential solutions we had two major goals in mind:

Goal #1: Make the codebase easier to read and understand

Since we relied on AngularJS’s module names and dependency injection to resolve dependencies between modules, there were no explicit links between modules; locating the source of a function was often an arduous process of performing global searches on the codebase.

With a module bundler, it’s much easier to trace the origin of any piece of code when it’s imported via a `require()` call. The module path in the `require()` call explicitly tells us which file the dependency comes from.

Goal #2: Make the codebase ready for a future where it’s simple to start using:

With a module bundler, enabling ECMA2015+ language features and JSX is as simple as enabling Babel, e.g. via babel-loader, and using React, Redux, and its ecosystem of packages is simplified to `npm install` and `require()`.


This isn’t an exhaustive list of all of the reasons to use a module bundler like webpack, but these were the main reasons why we opted to switch.

Next week, we will cover how we switched to webpack, using an incremental approach to the migration.

[If you liked this article, click the little ❤️ on the left so other folks know. If you want more posts like this, follow EventMobi publication with the (Follow) button on the right!

Finally if solving problems like this seems up your alley, we’re hiring! Checkout our current open positions at http://www.eventmobi.com/careers/]

EventMobi

An inside look at how we build the ultimate Event…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store