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

CommonJS和ES6 Modules区别

CommonJS 和 ES Modules(ESM)的区别

CommonJSES Modules (ESM) 是 JavaScript 中两种主流的模块规范,分别用于不同场景(Node.js 与浏览器/现代 Node.js),核心区别体现在语法、加载机制、运行时行为等方面。

1. 语法差异(最直观的区别)

CommonJS
  • 导出:使用 module.exportsexports
  • 导入:使用 require()
// 导出(math.js)
function add(a, b) { return a + b; }
module.exports = { add };  // 整体导出
// 或 exports.add = add;  // 单个导出// 导入(index.js)
const math = require('./math.js');
console.log(math.add(1, 2)); // 3
ES Modules (ESM)
  • 导出:使用 export(命名导出)或 export default(默认导出)
  • 导入:使用 import
// 导出(math.js)
export function add(a, b) { return a + b; }  // 命名导出
// 或 export default { add };  // 默认导出// 导入(index.js)
import { add } from './math.js';  // 对应命名导出
// 或 import math from './math.js';  // 对应默认导出
console.log(add(1, 2)); // 3

2. 加载机制:运行时加载 vs 编译时加载

CommonJS:运行时动态加载
  • 模块加载发生在代码执行阶段(运行时),require() 是一个函数,执行时才会加载模块。
  • 支持动态导入(可在条件语句中加载模块):
  • CommonJs是动态语法可以写在判断里
// 合法:根据条件动态加载
if (condition) {const math = require('./math.js');
}
  • 加载的是模块的拷贝(值传递):导入后,模块内部的后续修改不会影响导入结果。
ESM:编译时静态加载
  • 模块加载发生在代码解析阶段(编译时),import 声明必须放在文件顶部,且不能在条件语句中使用(静态分析)。
  • ES6 Module静态语法只能写在顶层,不支持直接在条件语句中写 import,但可通过 import() 函数实现动态加载(返回 Promise):
// 合法:动态导入(ES2020 新增)
if (condition) {import('./math.js').then(({ add }) => console.log(add(1, 2)));
}
  • 加载的是模块的引用(引用传递):导入后,模块内部的修改会实时反映到导入处。

3. 模块依赖:动态依赖 vs 静态依赖

  • CommonJS:依赖关系在运行时确定,模块路径可动态生成(如拼接字符串):

CommonJS 是运行时解析
CommonJS 的模块加载是动态的,require()是一个运行时执行的函数,可以写在代码的任何位置(如条件语句、循环中)。模块的依赖关系只有在代码执行到require()语句时才会被解析和加载,无法在编译阶段(代码执行前)确定完整的依赖树。

const path = './math.js';
const math = require(path);  // 合法
  • ESM:依赖关系在编译时确定,模块路径必须是静态字符串(不能动态生成):

ES Modules 是编译时解析
ES Modules 的 import 声明是静态的,必须写在模块的顶层(不能嵌套在条件语句中)。浏览器或 JS 引擎会在代码执行前(编译阶段)就解析所有 import 声明,构建完整的模块依赖关系图,这种静态分析能力让 ESM 支持树摇(tree-shaking)、类型检查等编译时优化。

const path = './math.js';
import { add } from path;  // 报错!路径必须是静态的

4. 循环依赖处理

循环依赖指 A 依赖 B,B 同时依赖 A 的情况,两者处理方式不同:
CommonJS
  • 当模块循环引用时,require() 会返回已执行部分的 exports(可能不完整)。
  • 例:
// a.js
const b = require('./b.js');
console.log('a 中 b 的值:', b);  // { b: undefined, getB: [Function] }
module.exports = { a: 1 };// b.js
const a = require('./a.js');
console.log('b 中 a 的值:', a);  // {}(此时 a 尚未导出完成)
module.exports = { b: 2,getB: () => a.a  // 后续可通过函数获取完整值
};
ESM
  • 循环依赖时,模块会通过引用绑定保持关联,即使依赖未完全加载,也能获取到最终值。
  • 例:
// a.js
import { b, getB } from './b.js';
console.log('a 中 b 的值:', b);  // undefined(初始值)
export const a = 1;
console.log('a 中 getB():', getB());  // 1(获取到 a 的最终值)// b.js
import { a } from './a.js';
export let b = 2;
export const getB = () => a;  // 引用 a 的绑定,最终会获取到 1

5. 环境支持

  • CommonJS

    • 主要用于 Node.js(默认模块系统),浏览器不原生支持(需通过 Webpack 等工具转译)。
    • 模块文件扩展名可省略(Node.js 会自动补全 .js.json 等)。
  • ESM
    • 浏览器原生支持(需在 <script type="module"> 中使用)。
    • Node.js 从 v12 开始支持(需将文件扩展名改为 .mjs,或在 package.json 中设置 "type": "module")。

6. 顶层作用域

● CommonJS:
每个模块的顶层 this 指向 module.exports,且存在 module、exports、require 等内置变量。
● ES Modules:
顶层 this 为 undefined,没有 module、exports 等变量,只能通过 import/export 操作模块。

7. 加载方式

CommonJS:
○ 同步加载:模块加载会阻塞后续代码执行,适合服务器端(Node.js),因为文件存在于本地磁盘,加载速度快。
ES Modules:
○ 异步加载:模块加载不会阻塞代码执行,适合浏览器环境(网络请求可能延迟),且支持并行加载多个模块。

总结
● CommonJS 是 Node.js 的传统模块规范,适合服务器端,支持动态加载,但不支持 Tree-shaking。
● ESM 是 ES 标准模块规范,浏览器和现代 Node.js 均支持,静态加载支持 Tree-shaking,更适合前端工程化。

http://www.xdnf.cn/news/1231057.html

相关文章:

  • python:以支持向量机(SVM)为例,通过调整正则化参数C和核函数类型来控制欠拟合和过拟合
  • Autosar Nm-网管报文PNC停发后无法休眠问题排查
  • 区分「尊重」和「顺从」
  • 简化理解I2C总线
  • Android13文件管理USB音乐无专辑图片显示的是同目录其他图片
  • 【Django】-6- 登录用户身份鉴权
  • Piriority_queue
  • Java多线程入门-基础概念与线程操作
  • JVM中年轻代、老年代、永久代(或元空间)、Eden区和Survivor区概念介绍
  • ART数据库索引结构--ART,The adaptive radix tree论文细读
  • 技巧|SwanLab记录ROC曲线攻略
  • 如果esp_radar_train_stop()调用失败(比如训练未正常启动、持续时间不足、或其他配置未完成),那么:
  • 【相机】曝光时间长-->拖影
  • html5+css3+canvas长文转长图工具支持换行
  • sqli-labs:65个关卡的文章汇总
  • [BJDCTF2020]EasySearch
  • Python中元组,字典,集合的易错题(含解析)
  • C++音视频开发:基础面试题
  • C++ 指针常量 常量指针
  • Docker 镜像打包为 ZIP 文件便于分享和转发
  • 【python】转移本地安装的python包
  • C++ 模板初阶
  • 海洋大地测量基准与水下导航系列之九我国海洋PNT最新技术进展(下)
  • opencv学习(单模块匹配)
  • 初始C语言---第四讲(数组)
  • C# 的委托和事件 总结
  • kong网关集成Safeline WAF 插件
  • 【深度学习】【三维重建】windows11环境配置PyTorch3d详细教程
  • JAVA国际版同城服务同城信息同城任务发布平台APP源码Android + IOS
  • 【RK3568 RTC 驱动开发详解】