领先一步
VMware 提供培训和认证,以加快您的进度。
了解更多大约十年前,Adrian Colyer 撰写了一篇令人难忘的博客文章,对面向方面编程 (AOP) 做出了最佳解释:风格清晰简洁,内容准确,没有专业术语。如果您查看了本系列中较早的两篇文章,您可能会注意到我们在 Sagan 应用程序的客户端模块中的一些架构选择,包括**使用 JavaScript 模块**。
在这篇文章中,我想以 Adrian 文章的风格向您介绍 JavaScript 模块的基础知识:清晰、简洁、准确,没有专业术语!
如果像我一样,您有 Java 背景,一些 JavaScript 语言特性可能会让您觉得有点奇怪
简单的 Web 应用程序通常如下所示
<html>
<head>
<!-- scripts are loaded **sequentially** -->
<script src="jquery.js"></script>
<script src="widget.js"></script>
<!-- all objects are in the global namespace,
no way to isolate the code completely! -->
<script>
window.$; // this is jquery
</script>
</head>
</html>
开发人员经常尝试重用功能块并管理它们之间的依赖关系。在前面的情况下,这很难实现:您必须按正确的顺序声明脚本并避免名称冲突,**没有任何关于依赖关系的元数据**。随着应用程序的增长,这项任务将成为一场噩梦:想象一下,在没有包或依赖关系管理基础设施的情况下管理您的 Java 应用程序!
幸运的是,JS 社区非常清楚模块化的需求,在过去几年中,出现了一些被广泛采用的解决此问题的方法
AMD(异步模块定义) 就是其中之一
// defining a module that depends on "graphmodule",
// injected in the function definition as an argument
define(["graphmodule"],
function (graph) {
// this module exports a "draw" function
return function draw(data) {
return graph.piechart(data);
}
}
);
AMD 格式通常用于浏览器应用程序,因为
CommonJS 是另一种编写格式,通常用于服务器端的 Node.js 应用程序,但也用于浏览器应用程序。
/**
* Our module's dependencies and API
**/
// we fetch the graph module as a dependency
var graph = require('graphmodule');
// we decorate the `exports` variable to export our function
exports.draw = drawFunc;
/**
* API implementation
**/
function drawFunc(data) {
return graph.piechart(data);
}
您可能发现了一些与 AMD 的不同之处
define
中下一个版本的 JavaScript(技术上称为 ECMAScript 6)将标准化 JavaScript 模块化,尽管它使用的语法与我们上面看到的 AMD 或 CommonJS 格式略有不同。此外,ECMAScript 6 将解决该领域的许多问题,但也将提供用于定义类似 OO 的类的语法糖。
无论您在何处使用 JavaScript,无论是客户端还是服务器端,都考虑采用模块化方法——出于与我们在 Java 中使用相同的所有原因。掌握 JS 模块技术需要一个小的学习曲线,但结果是值得的。
如果您是 JavaScript 模块化的新手,我建议您查看“编写 CommonJS 模块”教程和我们在 Sagan 中使用的模块加载器:curl。一旦您感觉熟悉了,请查看我们在Sagan 应用程序中的模块定义。