16.2 JavaScript 中的模块

虽然 JavaScript 从来没有内置的模块,但是社区聚集于一种简单的模块风格,此模块风格在 ES5 和更早版本中通过库来实现。在 ES6 中也同样接受这种风格:

  • 每一个模块都是一块代码,在加载完成后执行。
  • 在这段代码中,可能有各种声明(变量声明,函数声明等等)。
    • 默认情况下,这些声明只是模块本地的。
    • 你可以把其中一些标记为导出,这样其它模块就可以引入了。
  • 一个模块不仅能够导出东西,也可以从其它模块中导入东西。可以通过模块标识符或者字符串访问那些模块:
    • 相对路径(‘ ../model/user ’):这些路径相对于当前模块。通常文件扩展名 .js 可以省略。
    • 绝对路径(‘ /lib/js/helpers ’):直接指向要引入的模块文件。
    • 名字(‘ utils ’):需要配置模块名和所指向模块的映射关系。
  • 模块是单例的。即便一个模块被引入了多次,仅会存在该模块的单一“实例”。
  • 一个客户端或服务器应用的执行开始于一个初始化模块。在一些模块系统里面(包括 ES6 ),初始化模块可以内嵌在 HTML 文件中(考虑 <script> 元素)。

这种模块形式避免了全局变量,唯一全局的东西就是模块标识符。

16.2.1 ES5 模块系统

在语言层面上没有显示支持的前提下, ES5 模块系统的良好运作令人印象深刻。两个重要的标准(很不幸两者不兼容)是:

  • CommonJS 模块 : 该规范主要实现于 Node.js 中( Node.js 模块有一些特性超越了 CommonJS )。特点:
    • 紧凑的语法
    • 为同步加载设计
    • 主要用于服务器端
  • 异步的模块定义( AMD ): 该标准最流行的实现是 RequireJS。特点:
    • 稍微复杂的语法,使 AMD 能够不借助于 eval() (或者说是一个编译步骤)。
    • 为异步加载设计
    • 主要用于浏览器端

上面是目前情况的一个简单说明。如果需要更深入的资料,可以参考 Addy Osmani 的 《 Writing Modular JavaScript With AMD, CommonJS & ES Harmony 》

16.2.2 ECMAScript 6 模块

ECMAScript 6 模块的目标是创建一种模块化方式,让 CommonJS 使用者和 AMD 使用者都乐于接受:

  • 类似于 CommonJS ,语法紧凑,倾向于导出单个内容,支持循环依赖。
  • 类似于 AMD ,直接支持异步加载和可配置模块加载。

通过语言层面上的支持, ES6 模块超越了 CommonJS 和 AMD (后面详细解释):

  • 语法比 CommonJS 更加紧凑。
  • 可以静态分析代码结构(比如静态检测,优化,等等)。
  • 比 CommonJS 更好地支持循环依赖。

ES6 模块标准有两个部分:

  • 声明式的语法(在引入和导出的时候)
  • 可编程的加载器 API :可以配置模块如何加载,并且可以按条件加载模块

results matching ""

    No results matching ""