How to Build Scalable Web Modules: Architecture, Packaging, and Dependency Management
This article explains how to achieve module scalability in web interactive systems by defining modules, encapsulating their style, structure, and logic, managing dependencies with Uniform Module Identifiers, flattening hierarchical relationships, and applying scheduling strategies for display, refresh, and messaging.
In the second article of the series "Building Highly Scalable Web Interactive Systems", we focus on the scalability of individual modules.
Module Scalability
A web interactive system should support:
Extensibility – quickly respond to new functional requirements.
Reducibility – remove or replace degraded modules with minimal changes.
What Is a Module?
A module is an independent unit split from the system that can interact with users to complete a specific function.
Module Composition
Each module consists of three elements:
Style – defines the visual appearance.
Structure – defines the HTML markup.
Logic – implements the functional behavior.
Module Encapsulation
These elements can be packaged together, for example in an module.html file:
<!-- Module style -->
<style>
.m-mdl-1 .a {color:#aaa;}
.m-mdl-1 .b {color:#bbb;}
/* ... */
</style>
<!-- Module structure -->
<div class="m-mdl-1">
<p class="a">aaaaaaaaaaaaaaaaaaa</p>
<p class="b">bbbbbbbbbbbbbbbbbbb</p>
</div>
<!-- Module logic -->
<script>
(function(){
var a = 'aaa';
var b = 'bbb';
// ...
})();
</script>To avoid premature execution, the module’s elements can be stored as text, for example using textarea tags:
<!-- Module style -->
<textarea name="css">
.m-mdl-1 .a{color:#aaa;}
.m-mdl-1 .b{color:#bbb;}
/* ... */
</textarea>
<!-- Module structure -->
<textarea name="html">
<div class="m-mdl-1">
<p class="a">aaaaaaaaaaaaaaaaaaa</p>
<p class="b">bbbbbbbbbbbbbbbbbbb</p>
</div>
</textarea>
<!-- Module logic -->
<textarea name="js">
(function(){
var a = 'aaa';
var b = 'bbb';
// ...
})();
</textarea>Dependency Management
Modules often depend on one another. A simple single‑page application example is illustrated below:
The system includes components such as log management, blog settings, account management, etc., each represented as a module.
Traditional hierarchical patterns like PAC and HMVC suffer from strong coupling, deep event propagation, and costly changes when modules are added or removed.
Uniform Module Identifier (UMI)
We introduce a Uniform Module Identifier (UMI) to decouple modules from their implementations. UMI follows URI‑like path rules, e.g., /m/m0/, starts with a slash, and private modules start with /?. The path encodes the parent‑child relationship.
Each UMI maps to a concrete module file, allowing independent addition, removal, or modification of modules without touching business logic.
Flattening Dependencies
By abstracting the hierarchical tree into a flat list of UMIs, the dependency graph becomes a simple tree where each node corresponds to a module file.
Module Composition
Modules can be categorized as container providers or container users; a module may serve both roles, enabling arbitrary composition.
Configuration example for composing modules:
'/m/blog/list/':{
module:'module/layout/blog.list/index.html',
composite:{
box:'/?/blog/box/',
tag:'/?/blog/tag/',
list:'/?/blog/list/',
clazz:'/?/blog/class/'
}
}Scheduling Strategy
After flattening, modules are assigned to developers, built, and then integrated according to the dependency tree. Modules transition through four states:
Build – construct the module structure.
Show – render the module in its container.
Refresh – fetch and display data based on input.
Hide – release resources while keeping the module in memory.
The scheduler controls transitions between these states.
Module Display Process
When a user requests a module (e.g., /m/blog/list/), the system:
Loads implementation files registered along the path from root to target.
Ensures all ancestor modules are displayed before showing the target.
Attempts to display the target once its ancestors are ready.
Module Switch Process
Switching from one module to another follows four steps: find the common parent, hide modules from the source to the common node, refresh modules from the root to the common node, and finally show modules from the common node to the target.
Message Channels
Two communication patterns are recommended:
Point‑to‑point – a module sends a message to a specific UMI.
Publish/Subscribe – a module declares messages it can emit; others subscribe to them.
The article concludes by promising a concrete example using NetEase's NEJ framework in the final installment.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITFLY8 Architecture Home
ITFLY8 Architecture Home - focused on architecture knowledge sharing and exchange, covering project management and product design. Includes large-scale distributed website architecture (high performance, high availability, caching, message queues...), design patterns, architecture patterns, big data, project management (SCRUM, PMP, Prince2), product design, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
