JS 中由于历史原因有2种语言模块化的方式,分别为cjsesm; esmES Module的简称,另一种是Node.js使用的CommonJScjs;

那么2种模块化有哪些差异呢?

语法差异

我们讨论的是语言模块化的差异,那么语法上的差异主要来自于导入导出模块上的差异化;

ES Module 的导入导出

// 导入
import ModuleA from 'ModuleA'; 
import { moduleBFunction } from 'ModuleB'; 

// 导出
export const moduleAFunction = () => void;
export default function ModuleA() {};

CommonJS 的导入导出

// 导入
const { default: ModuleA }  = require('ModuleA');
const { ModuleB }  = require('ModuleB');

// 导出
exports.default = function ModuleA() {};
exports.moduleAFunction = () => void;

动态导入差异

  • ESM 支持动态导入,你可以在代码中使用 import() 来异步加载模块。
  • CommonJS 不支持动态导入,通常使用第三方库(如 require.ensure)来实现异步加

加载差异

  • ESM 在编译时进行加载和分析,有利于树摇等动作;
  • CommonJS 是运行时加载和分析的,模块在需要时按需加载;

顶级作用域差异

  • 在 ESM 中,每个模块都有自己的顶级作用域,变量不会泄漏到全局作用域。
  • 在 CommonJS 中,模块的变量会泄漏到全局作用域中。

浏览器支持差异

  • ESM 在现代浏览器中得到了广泛支持,可以在前端代码中使用。(Vite、Umi、Next就都有利用这个特性)
  • CommonJS 主要用于服务器端代码,但需要转换为 ESM 才能在浏览器中使用。