返回

模块的过去、现在和未来:理解 ESM 和 CJS 的共存以及 Node 完善自身功能的努力

前端

模块化的前世今生

模块化一直是 JavaScript 开发中的一大核心概念,它允许我们将代码分成更小的、可复用的部分,从而提高代码的可维护性和可扩展性。在 JavaScript 的早期,模块化主要通过 CommonJS (CJS) 规范来实现,CJS 规范定义了一套加载模块和导出模块的方法,并在 Node.js 中得到了广泛应用。

随着 JavaScript 的不断发展,新的模块化规范 ECMAScript Modules (ESM) 应运而生。ESM 规范由 TC39 定义,它提供了一种更现代、更标准化的模块化方式,并得到了各大浏览器的支持。与 CJS 相比,ESM 具有许多优点,例如:

  • 更简洁的语法:ESM 使用 importexport 来加载和导出模块,语法更加简洁明了。
  • 更高的安全性:ESM 模块是按需加载的,只有在需要的时候才会加载,这可以减少代码的体积并提高安全性。
  • 更强的可移植性:ESM 模块可以在浏览器和 Node.js 中同时使用,这使得代码的移植性更强。

ESM 和 CJS 的共存

由于 CJS 和 ESM 规范的差异,在实际开发中,我们经常会遇到 ESM 和 CJS 模块共存的情况。为了解决这个问题,Node.js 引入了对 ESM 模块的支持,并允许在同一个项目中同时使用 ESM 和 CJS 模块。

Node.js 对 ESM 模块的支持主要通过以下方式实现:

  • 提供了 --experimental-modules 选项,允许用户在命令行中启用 ESM 模块的支持。
  • 在 Node.js 的核心模块中添加了对 ESM 模块的支持,使得这些模块既可以使用 CJS 方式加载,也可以使用 ESM 方式加载。
  • 提供了 package.json 文件中的 type 字段,允许用户指定包的模块类型,以便 Node.js 可以正确加载该包。

Node 完善自身功能的努力

为了弥补 package 未导出可能被滥用了的情况,Node 顺道完善了自身的功能,主要体现在以下几个方面:

  • 在 Node.js 13 中,添加了 --require 选项,允许用户在命令行中指定需要加载的 ESM 模块。
  • 在 Node.js 14 中,添加了 --loader 选项,允许用户在命令行中指定 ESM 模块加载器。
  • 在 Node.js 15 中,添加了对 ESM 模块的原生支持,使得 ESM 模块可以直接在 Node.js 中加载,而无需使用任何额外的加载器。

模块化的未来发展

随着 JavaScript 的不断发展,模块化也将继续演进。未来的模块化可能会呈现以下几个趋势:

  • ESM 将成为主流:ESM 模块的优势将会使其成为主流的模块化方式,CJS 模块将逐渐被淘汰。
  • 模块联邦化:模块联邦化是一种新的模块化方式,它允许我们将多个模块组合成一个更大的模块,这可以提高代码的可维护性和可扩展性。
  • 动态模块化:动态模块化是一种新的模块化方式,它允许我们在运行时加载模块,这可以提高代码的灵活性。

结语

模块化是 JavaScript 开发中的一大核心概念,随着 JavaScript 的不断发展,模块化也将继续演进。ESM 模块将会成为主流,模块联邦化和动态模块化也将成为新的发展趋势。