Modules – a study on Javascript Module Definition

“Good authors divide their books into chapters and sections; good programmers divide their programs into modules. Like a book chapter, modules are just clusters of words (or code, as the case may be). Good modules, however, are highly self-contained with distinct functionality, allowing them to be shuffled, removed, or added as necessary, without disrupting the system as a whole.”
This could be a nice explanation on what are modules. This project tries to explore javascript module definition.

http://pedroluisf.com/wp-content/uploads/2016/12/JavaScript_logo.svg_.png
http://pedroluisf.com/wp-content/uploads/2016/12/RequireJS.png
http://pedroluisf.com/wp-content/uploads/2016/12/Browserify.png
http://pedroluisf.com/wp-content/uploads/2016/12/JSPM.png
http://pedroluisf.com/wp-content/uploads/2016/12/Webpack.png

Project Description

“Good authors divide their books into chapters and sections; good programmers divide their programs into modules.
“Like a book chapter, modules are just clusters of words (or code, as the case may be).
“Good modules, however, are highly self-contained with distinct functionality, allowing them to be shuffled, removed, or added as necessary, without disrupting the system as a whole.”

This is part of a very nice article I found explaining what modules are and that can be found here. I do recommend having a read as it can shed a light on the subject, as it did to me.

In this project, I did not try to cover the module pattern in Javascript, but rather look at module definitions. Those are:

  • AMD (Asynchronous Module Definition)
  • CommonJS
  • UMD (Universal Module Definition)
  • ES6

Each of these module definitions has their pros and cons, and there is no one rule to fit all, but rather a technical decision based on the context to use. Bellow you can find a very short description of the modules.

Show full module description

AMD is used a lot when serving resources to a frontend application. The reason is that the dependencies are downloaded asynchronously and only when necessary. Is also important to know that the application only runs when all those dependencies are met. Aside from asynchronicity, another benefit of AMD is that your modules can be objects, functions, constructors, strings, JSON and many other types.

CommonJS is widely used on backend applications and one of the reasons is that CommonJs is compatible with io, filesystem, and other server-oriented features. On the other hand, unlike AMD, CommonJS only supports objects as modules. One very know application of CommonJs is within NodeJS.

UMD is essentially a way to use either of the two, while also supporting the global variable definition. As a result, UMD modules are capable of working on both client and server. This is especially useful for projects that require support for both AMD and CommonJS features.

The “native” javascript way to addressing modules is implemented in the latest version of javascript (ES6 or ES2015) and it has some benefits over the “emulated” solutions presented before. A compact and declarative syntax and asynchronous loading, better support for cyclic dependencies and live read-only views of the exports.

SystemJS is a module loader that can import modules at run time in any of the popular formats used today (CommonJS, UMD, AMD, ES6). It is built on top of the ES6 module loader polyfill and is smart enough to detect the format being used and handle it appropriately. SystemJS can also transpile ES6 code (with Babel or Traceur) or other languages such as TypeScript and CoffeeScript using plugins.

Collapse module description

The project consists of several mini-projects each with a different strategy for handling the Javascript modules.

The first project (blank) contains the source code. It shows a simple list of users and allows for adding and removing users. This project contains the full application, however, it will not run in the browser, because the browser does not know how to load or interpret javascript modules.

The version of javascript we use is ES6 or ES2015. It is used babel to transpile it into ES5.

The modules are defined in a multitude of ways, having some files using the CommonJS definition, some other using the ES6 module definition and some others using AMD.
The goal is to bundle the application together regardless of the module definition used and present a final solution that will run using the bundler of choice.

There are 4 different bundlers used: RequireJS, Browserify, Webpack and JSPM.

Technology Stack

These are javascript projects, so this was the only language used. jQuery and lodash were also added, but only for scaffolding the template.

The majority of the libraries/plugins bellow were obtained using the package manager npm for the development dependencies and bower for the frontend dependencies.

The javascript used was version ES6 or ES2015. Because current browsers do not fully support that, we had to transpile the code into ES5 and we used Babel for it.

As a task manager, we used Gulp. That would allow us to work together with the babel modules.

We also used a less gulp module for handling the CSS preprocessing. This could easily be changed into a sass plugin.

We used RequireJSBrowserify, JSPM and Webpack for module bundling and creation, each of them in its separate project.

Demo

You can see a running demo of these projects in the following links:

AMD with RequireJS

CommonJS with Browserify

SystemJS with JSPM

Webpack

Github

Link for Github Repo

Leave a Reply

Your email address will not be published. Required fields are marked *