Frontend Development 16 min read

A Review of Frontend Moduleization Development and Tooling

This article reviews the evolution of frontend moduleization over the past decade, discusses the problems of early script inclusion, presents various solutions such as namespaces, closures, CommonJS, ES6 modules, and modern build tools, and illustrates each approach with concrete JavaScript code examples.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
A Review of Frontend Moduleization Development and Tooling

1. The Days Without Moduleization

In the early days JavaScript was used only for simple form validation and basic interactions, often written directly inside server‑side templates, resulting in chaotic, monolithic scripts.

2. Traditional Moduleization

As AJAX popularized, code size exploded, prompting developers to split functionality into smaller, reusable modules.

Early moduleization relied on plain JavaScript without any formal system like Require, AMD, or SeaJS, requiring developers to manually organize code.

The main goals were code reuse, clearer structure, and easier maintenance.

Example code (Example 1):

function show(element) { // display an element }
function close(element) { // hide an element }

These functions would typically be placed in a utils.js file and referenced in HTML (Example 2):

<body>
    <script src="lib/utils.js"></script>
    <script src="lib/page-1.js"></script>
    <script src="lib/page-2.js"></script>
</body>

2.1 Problems

Global variable conflicts when different pages define functions with the same name.

Manual dependency management; scripts must be loaded in the correct order, which becomes complex in large projects.

2.2 Attempts to Solve the Problems

2.2.1 Code Extraction

var utils = {
    _name: ‘baotong.wang’,
    show: function(element) {},
    close: function(element) {}
}

2.2.2 Namespaces

var com.company.departure.team.utils = {};

2.2.3 Closure Encapsulation (Immediately‑Invoked Function Expression)

(function() {
    var Company = Company || {};
    Company.Base = Company.Base || {};
    var _name = ‘baotong.wang’;
    function show() {}
    function close() {}
    Company.Base.Util = { show: show, close: close };
})();

2.2.4 Dependency Management

Early solutions such as Baidu’s Tangram and Qwrap used explicit dependency arrays, but they were limited and not widely adopted.

2.3 Tools of the Era

2.3.1 Code Concatenation – merging multiple scripts into a single file to reduce HTTP requests, while keeping shared libraries separate for caching.

2.3.2 Code Minification – compressing JavaScript to improve load speed (e.g., YUI Compressor).

3. The Arrival of Node

Node.js (2009) introduced npm, enabling a rich module ecosystem and the CommonJS module format for the frontend.

3.1 CommonJS Overview

CommonJS defines a simple module system where each file has its own scope, exports are assigned to module.exports , and modules are loaded with require() .

3.2 npm Ecosystem

npm provides a central repository for reusable packages, and CommonJS natively supports locating modules in node_modules .

3.3 Node for Frontend Developers

Node’s JavaScript runtime allowed frontend engineers to write build tools (grunt, gulp, browserify, webpack) that automate module bundling and other tasks.

4. Modern Moduleization Solutions

4.1 CommonJS Details

Each file is a module with its own private scope.

The module object represents the current module.

module.exports defines the public API.

require loads another module and returns its exports .

If a module cannot be found, an error is thrown.

Example implementation:

// module.js
module.exports = {
    func: function() {},
    field: "string"
};
module.exports.show = function() {};

// usage
var Base = require("../base.js");
var page = require("./file.js");
page.show();

4.2 Other Patterns

AMD (RequireJS) and CMD (SeaJS) provide asynchronous loading for browsers, but CommonJS remains dominant in many large Chinese companies.

4.3 Refactoring Example

Transforming the earlier closure example to CommonJS:

// module.js
var _name = 'baotong.wang';
function show() { alert(_name); }
function close() {}
module.exports = { show, close };

// page.js
var mod = require('./module.js');
mod.show();

4.4 Browser Support

Since browsers do not understand require , tools like Browserify, Fekit, and YKit convert CommonJS modules into browser‑compatible bundles.

4.5 Fekit Compilation Process

Fekit is a Node‑based CLI that parses CommonJS, supports requiring CSS, and handles internal module repositories. The core wrapper generated for each module looks like:

;(function(__context) {
    var module = {
        id: "{{md5Key}}",
        filename: "{{fileName}}",
        exports: {}
    };
    if (!__context.____MODULES) { __context.____MODULES = {}; }
    var r = (function(exports, module, global) {
        // ---------- original file code ----------
        {source}
        // ---------- original file code ----------
    })(module.exports, module, __context);
    __context.____MODULES["{{md5Key}}"] = module.exports;
})(this);

4.6 ES6 Modules

ES6 introduces import and export . In practice, Babel transpiles them to CommonJS ( require / module.exports ) for compatibility.

5. Summary

This article reviewed the history of frontend moduleization, highlighted early problems, described the rise of CommonJS and related tooling, and briefly mentioned ES6 module syntax, providing code snippets to illustrate each stage.

frontendJavaScriptBuild ToolsCommonJSES6nodemoduleization
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.