esm 与 cjs 的区别
esm 与 cjs 的区别
JS 中由于历史原因有2种语言模块化的方式,分别为cjs
与esm
; esm
是ES Module
的简称,另一种是Node.js使用的CommonJS
及cjs
;
那么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 才能在浏览器中使用。
- 语法差异
- ES Module 的导入导出
- CommonJS 的导入导出
- 动态导入差异
- 加载差异
- 顶级作用域差异
- 浏览器支持差异