JavaScript 模块化 (没有那些花哨的术语)

工程 | Brian Clozel | 2014年4月11日 | ...

大约十年前,Adrian Colyer 写了一篇 令人难忘的博客文章,给出了关于面向切面编程 (AOP) 的最佳解释:清晰简洁的风格,准确的内容,没有花哨的术语。如果您看过本系列之前的 两篇 文章,您可能已经注意到我们在 Sagan 应用程序的 客户端模块 中的一些架构选择,包括 使用 JavaScript 模块

在这篇文章中,我想以 Adrian 的文章风格向您介绍 JavaScript 模块的基础知识:清晰、简洁、准确,没有花哨的术语!

为什么 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 应用程序!

了解 JavaScript 编写格式:commonJS 和 AMD

幸运的是,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 有一些不同之处

  • 这种编写格式可以在浏览器 服务器上使用!
  • 因此您可以在无头浏览器 Node.js 单元测试中测试您的模块!
  • 模块定义没有包装在 define

接下来是什么?

下一个版本的 JavaScript(技术上称为 ECMAScript 6)将 标准化 JavaScript 模块化,尽管使用的语法与我们上面看到的 AMD 或 commonJS 格式略有不同。 此外,EcmaScript 6 将解决该领域的许多问题,还将提供语法糖来定义类似 OO 的类。

无论您在哪里使用 JavaScript,无论是客户端还是服务器端,都请考虑采用模块化方法 - 出于我们在 Java 中使用的所有相同原因。 熟练掌握 JS 模块技术需要一个小的学习曲线,但结果是值得的。

如果您是 JavaScript 模块化的新手,我建议查看 “编写 CommonJS 模块”教程 和我们在 Sagan 中使用的模块加载器:curl。 熟悉之后,请查看我们在 Sagan 应用程序中的模块定义

获取 Spring 新闻通讯

与 Spring 新闻通讯保持联系

订阅

更上一层楼

VMware 提供培训和认证,以加速您的进步。

了解更多

获得支持

Tanzu Spring 在一个简单的订阅中为 OpenJDK™、Spring 和 Apache Tomcat® 提供支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部