返回
模块的过去、现在和未来:理解 ESM 和 CJS 的共存以及 Node 完善自身功能的努力
前端
2024-02-07 04:42:12
模块化的前世今生
模块化一直是 JavaScript 开发中的一大核心概念,它允许我们将代码分成更小的、可复用的部分,从而提高代码的可维护性和可扩展性。在 JavaScript 的早期,模块化主要通过 CommonJS (CJS) 规范来实现,CJS 规范定义了一套加载模块和导出模块的方法,并在 Node.js 中得到了广泛应用。
随着 JavaScript 的不断发展,新的模块化规范 ECMAScript Modules (ESM) 应运而生。ESM 规范由 TC39 定义,它提供了一种更现代、更标准化的模块化方式,并得到了各大浏览器的支持。与 CJS 相比,ESM 具有许多优点,例如:
- 更简洁的语法:ESM 使用
import
和export
来加载和导出模块,语法更加简洁明了。 - 更高的安全性: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 模块将会成为主流,模块联邦化和动态模块化也将成为新的发展趋势。