当前位置: 首页 > news >正文

ESM和CommonJS详解

概述

ESMCommonJS 是前端非常常见的两种规范或模块标准,本文将重点讲述这两者的定义、适用范围以及区别。

ESM

ESMECMAScript Modules,是 Javascript 的官方模块化标准,旨在统一 Javascript 的模块化机制。

ESM 的导出和导入
  • 导出:使用 export 关键词导出模块内容,可以是命名导出或默认导出
/** a.js */
export const obj = () => {console.log(5);
};//默认导出
const greet = () => {console.log("Hello World");
};
export default greet;
  • 导入:使用import语法来加载模块
/** b.js */
import greet, { obj } from "../a.js";
特点
  • 异步加载:支持异步加载,适合浏览器环境,与 Javascript 的动态加载功能兼容良好
  • 静态分析:支持静态分析,意味着在编译时可以检查模块的依赖关系,对于优化和工具链支持如tree-shaking很有帮助
  • 浏览器支持:ESM 可以直接在浏览器中使用,只需要写成<script type='module'>即可
  • 严格模式:默认在严格模式下运行

CommonJS

CommonJS是一个 Javascript 模块标准,主要用于 Node.js 环境

模块的导入导出
  • 导出:使用module.exportsexports对象来导出模块内容
/** a.js */
module.exports = () => {console.log("commonjs");
};
  • 导入:使用require()函数来加载模块
/** b.js */
const greet = require("./a.js");
greet();
特点
  • 同步加载:CommonJS 是同步加载的,所以模块正在代码执行时会被即时加载,这可以用SSR
  • 文件系统:CommonJS 模块依赖于 Node.js 的文件系统,因此不适用于浏览器
  • 模块缓存:CommonJS 在第一次加载模块后,会缓存模块导出的结果,因此如果后续加载相同的模块时会使用缓存,避免重复加载

ESMCommonJS对比

  • ESM使用import加载模块时,必须放在文件的最顶部,而CommonJS使用require则没有这个限制
  • ESM规范对应的标准文件后缀名是.mjs,而CommonJS则是.cjs
符号绑定(Live Binding)

ESM中有个Live Binding的概念,有的人称之为符号绑定。在开发中,定义的变量在程序编译之后都会被转化为地址,而执行变量就是符号。所谓的符号绑定就是将程序中使用到的变量名等,换成对应的地址,方便查找相应的数据。

前面提到ESM是在编译阶段就可以确定好模块间的依赖关系,因此对于变量也可以在这个时间进行确定地址,进行替换,这就是静态绑定

CommonJS是运行时,它不存在符号绑定这个概念,因此只有在程序运行时进行地址查找和替换,这就称为动态绑定

举例说明:
ESM

/** a.mjs */
export const obj = {number: 0,
};const add = () => {obj.number += 1;
};export default add;
/** b.mjs */
import es, { obj } from "./a.mjs";es();
console.log("🚀 ~ es:", es, obj);

CommonJS

/** a.cjs */
const obj = {number: 0,
};const add = () => {obj.number += 1;
};module.exports = { add, obj };
/** b.cjs */
const { add, obj } = require("./a.cjs");add();
console.log("🚀 ~ add:", add, obj);

分别定义导出文件a.mjsa.cjs和导入文件b.mjsb.cjs,通过执行node b.mjsnode b.cjs,得到如下结果:

在这里插入图片描述

这说明无论是ESM还是CommonJS,都会进行内存地址共享,引用的是同一个数据


http://www.mrgr.cn/news/16490.html

相关文章:

  • vue3 element-plus 按下回车键搜索方法
  • 新160个crackme - 043-riijj_cm_20041121
  • jmeter响应断言、json断言、断言持续时间操作
  • mysql基础语法——个人笔记
  • Go 1.19.4 文件读写操作-Day 14
  • 100天带你精通Python——第8天面向对象编程
  • 【鬼灭之刃学英语 立志篇】2、义勇对炭治郎的怒斥
  • SAP LE学习笔记07 - MM与WM跨模块收货到仓库的流程中 如何实现 先上架再入库
  • 如何使用vcftools提取特定的染色体
  • JMeter 接口自动化测试:以搜索功能为例的实现思路详解
  • IT 行业的就业情况
  • 665.非递减数列
  • 2024年四款SD卡数据恢复工具使用体验推荐~
  • LabVIEW呼吸机测试系统开发
  • 实测数据处理(RD算法处理)——SAR成像算法系列(十)
  • 数据库课程设计mysql
  • 通过Dot1q终结子接口实现VPN接入
  • ConcurrentModificationException 异常出现的原因和解决方案
  • 入坑大模型18个月的反思与贩私
  • 浪潮GS企业管理软件 UploadListFile 文件上传致RCE漏洞复现