Modules in JavaScript

Hello “ES6” aka “ECMAScript 2015” Modules

In the dark times of Javascript, everything in Javascript application was smashed together like jQuery soup. You would use jQuery to pick at the DOM via targeting. Things lived in ugly global namespaces. Parts of the codebase had no separation, composability, or dependency management. Like I said, it was dark times.

Several early pioneers took computer science ideas from other languages and made attempts at making Javascript into a well-encapsulated language. They were called things like Object literal pattern, IFFE (“iffy”), CommonJS, and AMD (Asynchronous Module Definition).

Then, “ES6 Modules” become the de-facto way to write modern JS. Also known as ES Modules, you’ll want to check out my blog post specifically designed to describe

At the top level of your JS file, you will want to first define things, and then export them.

You can export varletconst or classes.

./modules/square.js

export const foo = 'square';

export function drawSquare(canvasRenderingObject, length, x, y, color) {
  canvasRenderingObject.fillStyle = color;
  canvasRenderingObject.fillRect(x, y, length, length);

  return {
    length: length,
    x: x,
    y: y,
    color: color
  };
}
export { foo, draw };

Here, we’ve created a constant foo and function drawSquare.

When you export this way you must use curly braces, and you are creating named exports. That means in another file, when we explicitly pull these things into the scope of our other file module, we will pull them in as these names.

Then, we’ve exported both out of this file.

In another file, more specifically, in the place where we want to use these things, we are going to import them:

import { foo, drawSquare } from './modules/square.js';

Note the curly braces used here to pull in named exports.

If, on the other hand, we had used the default export, we would be setting one export as the primary thing exported out of the file:

You can do this one of two ways:

  1. Use a local constant up top, and then expor that local constant (this is common in React)
const InputWidget = () => {

}

export default InputWidget;

When imported, it looks like so:

import InputWidget from './modules/InputWidget.js';

Notice the lack of curly braces. This is because there is only one default export allowed per module, and we know that InputWidget is it. The above line is basically shorthand for:

import {default as InputWidget} from './modules/InputWidget.js';

If, on the other hand, you wanted the default export to be named something else, you would do this

import {default as SomethingElse} from './modules/InputWidget.js';

Now, even though the fact that you defined it as InputWidget in the exported file doesn’t matter, it will be SomethingElse in the place where it is imported.