快速了解JavaScript的模块

概述

随着现代 JavaScript 开发 Web 应用变得复杂,命名冲突和依赖关系也变得难以处理,因此需要模块化。而引入模块化,可以避免命名冲突、方便依赖关系管理、提高了代码的复用性和和维护性,因此,在 JavaScript 没有模块功能的前提下,只能通过第三方规范实现模块化:

  • CommonJS:同步模块定义,用于服务器端。
  • AMD:异步模块定义, 用于浏览器端。
  • CMD:异步模块定义,用于浏览器端。
  • UMD:统一 COmmonJSAMD 模块化方案的定义。

它们都是基于 JavaScript 的语法和词法特性 “伪造” 出类似模块的行为。而 TC-39 在 ECMAScript 2015 中加入了模块规范,简化了上面介绍的模块加载器,原生意味着可以取代上述的规范,成为浏览器和服务器通用的模块解决方案,比使用库更有效率。而 ES6 的模块化的设计目标:

  • CommonJS 一样简单的语法。
  • 模块必须是静态的结构
  • 支持模块的 异步加载同步加载,能同时用在 serverclient
  • 支持模块加载的 ‘灵活配置’
  • 更好地支持模块之间的循环引用
  • 拥有语言层面的支持,超越 CommonJSAMD

ECMAScript 在 2015 年开始支持模块标准,此后逐渐发展,现已经得到了所有主流浏览器的支持。ECMAScript 2015 版本也被称为 ECMAScript 6。

模块

ES6 模块借用了 CommonJSAMD 的很多优秀特性,如下所示:

  • 模块代码只在加载后执行。
  • 模块只能加载一次。
  • 模块是单例。
  • 模块可以定义公共接口,其他模块可以基于这个公共接口观察和交互。
  • 模块可以请求加载其他模块。
  • 支持循环依赖。

ES6 模块系统也增加了一些新行为。

  • ES6 模块默认在严格模式下执行。
  • ES6 模块不共享全局命名空间。
  • 模块顶级 this 的值是 undefined;常规脚本中是 window
  • 模块中的 var 声明不会添加到 window 对象。
  • ES6 模块是异步加载和执行的。

浏览器运行时在知道应该把某个文件当成模块时,会有条件地按照上述 ES6 模块行为来施加限制。与

// 支持模块的浏览器不会执行这段脚本 // 不支持模块的浏览器会执行这段脚本

总结

ES6 在语言层面上支持了模块,结束了 CommonJSAMD 这两个模块加载器的长期分裂状况,重新定义了模块功能,集两个规范于一身,并通过简单的语法声明来暴露。

模块的使用不同方式加载 .js 文件,它与脚本有很大的不同:

  1. 模块始终使用 use strict 执行严格模式。
  2. 在模块的顶级作用域创建的变量,不会被自动添加到共享的全局作用域,它们只会在模块顶级作用域的内部存在。
  3. 模块顶级作用域的 this 值为 undefined
  4. 模块不允许在代码中使用 HTML 风格的注释。
  5. 对于需要让模块外部代码访问的内容,模块必须导出它们。
  6. 允许模块从其他模块导入绑定。
  7. 模块代码执行一次。导出仅创建一次,然后会在导入之间共享。

浏览器对原生模块的支持越来越好,但也提供了稳健的工具以实现从不支持到支持 ES6 模块的过渡。

更多内容请关注公众号「海人为记
image

你可能感兴趣的:(程序员javascript前端)