• Home
  • blog
  • Understanding JavaScript Modules: Bundling & Transpiling

Understanding JavaScript Modules: Bundling & Transpiling

This article was peer reviewed by Dan Prince and Ravi Kiran. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

Most folks consider modules, dependency management and dynamic loading a basic requirement for any modern programming language—these are some of the most important features added to JavaScript in 2015.


Modules are used extensively in Node but our focus here will be on how we can use modules inside of the browser. We’ll explore a little history, navigate through the hazardous current landscape with the end goal of having a clear path forward and appreciation for the most important module bundlers for JavaScript today: Browserify, Webpack and jspm.

Finally we’ll look at how to use these tools with transpilers like CoffeeScript, TypeScript and Babel.

Modules Through the Ages

JavaScript has existed since 1995 and to this day no browser supports modules natively. Node and CommonJS were created in 2009 and the vast majority of packages in npm use CommonJS modules.

Browserify was released in 2011 and brought CommonJS modules to the browser allowing client-side JavaScript to require npm packages. The tool bundles up all of the required dependencies into a single JavaScript file.

The Past

A library such as jQuery adds $ to the global scope or window.

window.$ = function() { ... };

We include a script to a library and use the global objects it exposes.

<script src="jquery.js"></script>
$(function() { ... });

Your own application code was typically namespaced under a global like App to prevent polluting the global scope. Without this it’s only so long before you have name collisions and things fall apart.

var App = {};
App.Models = {};
App.Models.Note = function() {};

The Future

Libraries export objects in a common module format (ES6 modules).

export default function $() { ... }

We import a module into a local scope and use it.

import $ from 'jquery';

$(function() { ... });
  • No globals required 👍
  • Source order independence
  • Access to npm
  • No need to namespace your own application code
  • Dynamically load modules at any time as required

The Present

It’s really really complicated. First, there’s a variety of module formats out there in use:

Tools for bundling assets come in a variety of shapes and sizes:

Then there’s transpilers that you may want to use:

In addition, there are various libraries that allow dynamic loading of modules:

These are shortened lists of popular tools currently in use—it’s a minefield for beginners and experts alike. The cost of transpiling also highlights that you can mix and match a lot of these tools and get different results.

Let’s Consolidate Tooling in 2016

Front-end developers have been using build tools for a very long time but it’s only in the last few years that we’ve seen a build step become the norm. Tools like Sass and CoffeeScript helped make pre-processing mainstream but the momentum around ES6 has now got everyone on board.

I agree.

Gulp and Grunt have been very popular in the past few years, these tools allow you to write a series of transforms to pipe your assets through. They’ve been used to great effect and are still popular, though a lot of people choose to use the tools directly through npm – see Why I left Gulp and Grunt for npm Scripts and Guide to using npm as a Build Tool.

Personally, I don’t care for building asset pipelines any longer, what I’m looking for is minimal config tools that allow me to use modern tooling as needed: Things like Sass, Autoprefixer, Babel and Coffeescript, a proper module system and loader without having to worry about the implementation, configuration and ongoing maintenance. In essence, every developer has been investing time into creating assets pipelines over the last few years, that’s a lot of wheel re-invention going on and a lot of wasted hours.

The community is divided across tools like Browserify, Webpack, jspm, Sprockets and Gulp. That’s not really a problem, it’s just confusing for everyone trying to understand a clear path forward.

Clear Starting Points

There’s a few things we can agree on:

  • ES2015 modules are the one true future module format for JavaScript.
  • Babel is the ES2015 compiler of choice today.
  • Native loaders are still a while away from being available in browsers, a report on the Future of JavaScript by Telerik suggests that complete ES2015 support could take over two years given the module loading hurdle.
  • If you want to use modules now, that will very likely involve CommonJS at some point.

Let’s look at what minimal configuration setups look like using Browserify, Webpack and jspm, these are the most important JavaScript bundlers to know about today.

A New Project

mkdir modules-app
cd modules-app
npm init -y
npm install --save-dev browserify webpack jspm
mkdir src
touch src/{entry,lib}.js index.html

Update index.html in your favourite text editor

<!DOCTYPE html>
<html lang="en">
  <meta charset="utf-8">
  <script src="bundle.js"></script>

We’ll also need a server to run the code—for example live-server which is a great little zero-config HTTP server with live reload capability. Install it globally with npm install -g live-server and run live-server from the project root to start.

Continue reading %Understanding JavaScript Modules: Bundling & Transpiling%