使用RequireJS实现JavaScript模块化与延迟加载
本文通过对比传统脚本加载与RequireJS方案,详解如何利用RequireJS解决JavaScript文件间的依赖混乱问题。通过重构示例代码,展示如何定义模块依赖、实现按需加载,从而降低耦合度并提升Web应用性能。
RequireJS与JavaScript模块化加载概述
无论是简单的还是复杂的Web应用,通常都包含HTML、JavaScript和CSS文件。开发者常借助jQuery、Knockout、Underscore等第三方框架加速开发。这些框架经过验证且针对特定场景优化,直接使用比从零实现更高效。但随着应用复杂度增加,编写干净、低耦合且易维护的代码变得至关重要。本文将介绍如何使用RequireJS框架帮助开发者构建更模块化的代码,并通过延迟加载JavaScript文件来提升应用性能。
首先,我们将展示不使用RequireJS框架的情况,随后在后续章节中演示如何使用RequireJS对其进行重构。
以下HTML页面包含一个id为“message”的<p>元素。当用户访问该页面时,它将显示订单ID和客户姓名信息。
Common.js文件定义了两个模块:Order和Customer。showData函数与页面body结合,通过调用write函数将信息输出到页面。作为示例,showData函数中硬编码了ID为1,客户姓名为Prasad。
<!DOCTYPE html>
<html>
<head>
<title>JavaScript NonRequireJS</title>
<script src="common.js" type="text/javascript"></script>
</head>
<body>
<strong>Display data without RequireJS</strong>
<p id="message" />
<script type="text/javascript">
showData();
</script>
</body>
</html>
Common.JS
function write(message) {
document.getElementById('message').innerHTML += message + '</br>';
}
function showData() {
var o = new Order(1, "Prasad");
write("Order Id : " + o.id + " Customer Name : " + o.customer.name);
}
function Customer(name) {
this.name = name;
return this;
}
function Order(id, customerName) {
this.id = id;
this.customer = new Customer(customerName);
return this;
}
在浏览器中打开该页面,你将看到如下输出信息。

传统脚本加载存在的问题
尽管上述代码能够正常显示输出,但仍存在以下问题:
- Common.js文件包含了所有需要定义的函数(write、showData),且模块(Order、Customer)难以维护和复用。如果其他页面复用write函数并引用了上述JavaScript文件,也会导入该页面可能不需要的其他函数和模块。
- Order模块(在面向对象编程中称为“类”)在初始化过程中创建了Customer模块的实例。这意味着Order模块依赖于Customer模块。这种模块间的紧耦合使得未来在优化时难以进行重构与维护。
- 每次客户端请求该页面时,Common.js文件都会被载入DOM。在上面的示例中,尽管我们只需要在页面上输出信息,但仍将不需要的模块(Customer、Order)加载到了内存中。加载不必要的应用资源(JavaScript、CSS、图片文件等)会降低应用性能。
- Common.js文件中的模块可以被分离到不同的JavaScript文件中,但随着应用变得越来越复杂,很难判断JavaScript文件之间的依赖关系以及需要加载文件的顺序。
RequireJS框架处理了JavaScript文件间的依赖关系,并根据需要按顺序加载它们。
使用RequireJS重构应用
使用RequireJS搭建应用
现在让我们看看重构后的代码。以下HTML代码引用了Require.js文件。data-main属性定义了这个页面的唯一入口点。在下面的场景中,它告诉RequireJS在启动时加载Main.js。
<!DOCTYPE html>
<html>
<head>
<title>JavaScript RequireJS</title>
<script src="Require.Js" type="text/javascript" data-main="Main.js"></script>
</head>
<body>
<strong>Display data using RequireJS</strong>
<p id="message" />
</body>
</html>
Main.js入口配置
Main.js
由于该文件已通过data-main属性指定,RequireJS将尽快加载它。该文件使用RequireJS框架的函数来确定和定义对其他JavaScript文件的依赖关系。在下面的代码片段中,第一个参数表示依赖关系(依赖Order.js文件),第二个参数为一个回调函数。RequireJS分析所有依赖关系并载入它们,然后执行该回调函数。请注意,第一个参数的值(Order)必须与文件名一致(Order.js)。
require(["Order"], function (Order) {
var o = new Order(1, "Prasad");
write(o.id + o.customer.name);
});
Order.js模块定义
Order.js
RequireJS框架提供了一种定义和维护JavaScript文件间依赖关系的简便途径。下面代码中的define函数声明了Customer.js必须在处理Order回调函数前载入。
define(["Customer"],
function (Customer) {
function Order(id, custName) {
this.id = id;
this.customer = new Customer(custName);
}
return Order;
}
);
Customer.JS
Customer.js模块定义
该文件不依赖于任何其他JavaScript文件,因此define函数的第一个参数的值是一个空数组。
define([],
function () {
function Customer(name) {
this.name = name;
}
return Customer;
}
);
现在,用你的浏览器打开该应用,你将看到如下输出。需要注意的是,RequireJS只载入了必需的JavaScript文件。

总结
总结
在本文中,我们分析了RequireJS框架是如何处理JavaScript文件间的依赖关系并根据需要载入它们的。它能够帮助开发者写出更松耦合、更模块化且更具有可维护性的代码。
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
