Module definition – then and now

Before 2010 (approximately), there were very few agreed upon methods of loading large and complex JavaScript code bases within the browser. Soon, however, developers created the Asynchronous Module Definition (AMD) format. This was the first popular attempt at a standard that prescribed the definition of modules within JavaScript. It included both the ability to declare dependencies on each module and an asynchronous loading mechanism. This was a vast improvement upon the slow and blocking nature of multiple inline <script> tags.

RequireJS was a popular library that supported this format. To use it, you only needed to place a single entry point <script> in your document:

<script data-main="scripts/main" src="scripts/require.js"></script>

The data-main attribute here would specify the entry point of our code base, which itself would then load the initial set of dependencies and initialize the application, like so:

requirejs([
"navigationComponent",
"chatComponent"
], function(navigationComponent, chatComponent) {
// Initialize:
navigationComponent.render();
chatComponent.render();
});

Each dependency would then define itself and its own dependencies, like so:

// The Navigation Component AMD Module
define(
// Name of the module
'navigationComponent',

// Dependencies of the module
['utilA', 'utilB'],

// Definition of the module returned from function
function (utilA, utilB) {
return /* Definition of navigationComponent */;
}
);

This is similar in spirit to modules as now specified in the ECMAScript specification, except AMD is not related to any particular language syntax. It was entirely a community-driven effort to bring something like modules to JavaScript.

The fact that AMD prescribed that each module was defined within a callback, to which dependencies could be passed, meant that loading utilities such as RequireJS could load all dependencies asynchronously and then invoke the callback when it was done. This was a significant boost to frontend JavaScript at the time because it meant we could quite easily load massive dependency graphs in a way that eased the process of writing the code (less dependency juggling) and enabled the code to be loaded into the browser in a non-blocking and more performant fashion.

At a similar time to AMD, a new standards-driven effort started to emerge called CommonJS. This sought to make the require(...) syntax a standard in various non-browser environments, with the hopeful, eventual intention of such syntax being supported on the frontend as well. Here's an example of a CommonJS module (this may appear familiar if you're accustomed to programming in Node.js):

const navigationComponent = require('components/navigation');
const chatComponent = require('components/chat');

module.exports = function() { /* exported functionality */ };

This became the standard in various non-browser environments such as Node.js, SproutCore, and CouchDB. It was also possible to compile your CommonJS modules into browser-consumable scripts similar to AMD using the CommonJS Compiler. Sometime after this, around 2017, ES Modules emerged. This gave us language support for import and export statements, effectively solving the historical challenge of how to define modules in JavaScript:

// ES Modules

import navigationComponent from 'components/navigation';
import chatComponent from 'components/chat';

export default function() { /* do stuff */ };

In Node.js, such modules must have filename suffixes of .mjs instead of .js so the engine knows to expect import and export and not the conventional CommonJS module definition syntax. In the browser, such modules can be loaded by using <script type="module">. However, even with ES Modules supported in browsers, it's still arguably preferable to build and bundle your JavaScript into conventional non-modular script tags. This is due to factors of performance and compatibility across browsers. Not to worry though: we can still use ES Modules when writing our code! Tools such as Babel can be used to compile and bundle the latest JavaScript syntax into JavaScript that is compatible across many environments. It's typical to set up a tool such as Babel as part of your build and development process.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.150.55