ES Module(ESM,ES6 模块系统)和 CommonJS 是 JavaScript 中两种主流的模块规范,分别用于现代前端和 Node.js 环境(早期),它们在语法、加载机制、特性等方面有显著区别。以下是详细对比:

一、语法差异

1. 导出(Export)

ES Module:

使用 export 关键字,支持命名导出和默认导出,可在同一模块中混合使用。

运行
// 命名导出(多个)
export const name = 'foo';
export function func() {};// 默认导出(一个模块只能有一个)
export default { id: 1 };

CommonJS:

使用 module.exports 或 exports 导出,本质是导出一个对象(默认导出)。

运行
// 导出对象
module.exports = {name: 'foo',func: function() {}
};// 也可单独赋值(通过 exports 引用 module.exports)
exports.name = 'foo';
exports.func = function() {};

2. 导入(Import)

ES Module:

使用 import 关键字,支持导入命名成员、默认成员或整体导入。

运行
// 导入命名成员
import { name, func } from './module.js';// 导入默认成员(可自定义名称)
import obj from './module.js';// 整体导入(命名空间对象)
import * as mod from './module.js';

CommonJS:

使用 require() 函数导入,返回模块导出的对象。

运行
// 整体导入
const mod = require('./module.js');
console.log(mod.name); // 访问导出的成员// 解构导入(模拟命名导入)
const { name, func } = require('./module.js');

二、加载机制

1. 加载时机

ES Module:

  • 静态加载:导入和导出语句在代码解析阶段(编译时)执行,而非运行时。
  • 导入语句只能放在模块顶层(不能在 if、函数等代码块中),浏览器 / 引擎可提前分析模块依赖,实现树摇(Tree Shaking)(删除未使用的代码)。

CommonJS:

  • 动态加载:require() 在运行时执行,可根据条件动态导入(如在 if 语句中调用 require())。
  • 无法在编译时确定依赖关系,不支持树摇。

2. 模块加载方式

ES Module:

  • 异步加载:在浏览器中,ESM 通过
运行
// module.js
export let count = 0;
export function increment() { count++; }// main.js
import { count, increment } from './module.js';
increment();
console.log(count); // 输出 1(同步更新)

CommonJS:

  • 同步加载:在 Node.js 中,require() 是同步加载,适合服务端(文件读取快),不适合浏览器(会阻塞渲染)。
  • 值的拷贝:导入的是模块导出值的 “拷贝”,模块内部后续修改不会影响导入方。
运行
// module.js
let count = 0;
module.exports = {count,increment() { count++; }
};// main.js
const mod = require('./module.js');
mod.increment();
console.log(mod.count); // 输出 0(拷贝未更新)

三、模块标识与路径

ES Module:

  • 必须使用完整路径(包括文件扩展名,如 .js、.mjs),或通过配置(如 package.json 的 type: “module”)省略。
  • 支持绝对路径、相对路径和 URL(如 import 'https://cdn.example.com/module.js')。
运行
import './utils.js'; // 必须带 .js 扩展名(Node.js 中需配置)

CommonJS:

  • 可省略文件扩展名(.js、.json 等会被自动补全),支持查找 node_modules 中的模块。
运行
require('./utils'); // 自动补全为 ./utils.js
require('lodash'); // 从 node_modules 中查找

四、循环依赖处理

ES Module:

  • 遇到循环依赖(A 依赖 B,B 依赖 A)时,会返回 “未完成的模块实例”(部分导出已可用),后续代码执行时补充完整。
运行
// a.js
import { b } from './b.js';
export const a = 1;
console.log('a 中 b 的值:', b); // 输出 undefined(此时 b 尚未导出)// b.js
import { a } from './a.js';
export const b = 2;
console.log('b 中 a 的值:', a); // 输出 1(a 已导出)

CommonJS:

  • 循环依赖时,会缓存已执行的部分模块,返回 “缓存的导出对象”(可能不完整)。
运行
// a.js
const { b } = require('./b.js');
exports.a = 1;
console.log('a 中 b 的值:', b); // 输出 undefined(b 尚未导出)// b.js
const { a } = require('./a.js');
exports.b = 2;
console.log('b 中 a 的值:', a); // 输出 undefined(a 尚未导出)

五、适用环境

ES Module:

  • 现代浏览器(原生支持,需·<script type="module">)。
    Node.js 14.3+(需文件后缀为 .mjs 或 package.json 中设置 “type”: “module”)。
  • 前端工程化工具(Webpack、Vite 等)默认支持,是前端模块化的主流方案。

CommonJS:

  • 主要用于 Node.js 环境(默认模块系统),早期前端通过 Browserify、Webpack 等工具转换后使用。
  • 目前 Node.js 仍广泛兼容,但新项目更推荐 ESM。

六、核心区别总结

在这里插入图片描述

七、如何选择?

  • 前端项目:优先使用 ES Module,配合工程化工具实现树摇和优化。
  • Node.js 项目:新项目推荐 ES Module(“type”: “module”),旧项目兼容 CommonJS。
  • 需动态加载模块(如根据条件导入):可在 ESM 中使用 import() 函数(返回 Promise,支持动态加载),兼具静态分析和动态能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/93652.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/93652.shtml
英文地址,请注明出处:http://en.pswp.cn/web/93652.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

猫头虎AI分享|一款智能量化交易系统:QuantCell,从数据收集到策略执行全流程自动化

猫头虎AI分享&#xff5c;一款智能量化交易系统&#xff1a;QuantCell&#xff0c;从数据收集到策略执行全流程自动化 在当今金融市场中&#xff0c;量化交易系统已经成为越来越多投资者和机构的重要选择。无论是股票、期货还是加密货币&#xff0c;自动化交易与人工智能的结合…

直播美颜SDK架构揭秘:动态贴纸功能的实现原理与性能优化

如今&#xff0c;美颜SDK 已经不再只是“磨皮、美白”的基础工具&#xff0c;而是逐渐进化为一个涵盖 人脸识别、实时特效、动态贴纸交互 的复杂技术体系。尤其是 动态贴纸功能 的加入&#xff0c;让主播与观众之间的互动更加生动有趣&#xff0c;也成为提升用户粘性与平台差异…

Docker安装CDC

Docker安装CDC拉取镜像离线形式安装上传文件并创建docker-compose.yml把镜像加载到docker中启动容器连接数据库创建账号&#xff0c;并给账号授权设置wal_level确认wal_level的值创建链接查询连接状态使用kafdrop消息中看不到修改之前的信息怎么办补充拉取镜像 docker pull co…

如何在win服务器中部署若依项目

一、安装jdk的环境&#xff1a; 这一步很简单&#xff0c;直接拿到安装包双击安装即可。 二、配置jdk的环境变量默认安装的路径为&#xff1a;C:\Program Files (x86)\Java\jdk1.7.0_51安装完成之后进行环境变量配置右击计算机&#xff08;此电脑&#xff09;点击属性点击高级系…

CSS从入门到精通完整指南

第一部分&#xff1a;CSS基础入门1.1 什么是CSSCSS&#xff08;层叠样式表&#xff0c;Cascading Style Sheets&#xff09;是用于描述HTML文档外观和格式的样式语言。CSS将内容与表现分离&#xff0c;让HTML专注于内容结构&#xff0c;CSS专注于视觉效果。1.2 CSS语法结构选择…

重温k8s基础概念知识系列二(Pod)

文章目录1、Pod概念2、K8s 中的 Pod 的两种用法3、定义Pod4、Pod的创建资源5、Pod 模板6、容器探针7、总结干货8、 K8s Pod 经典面试题速查表Pod是Kubernetes中最小的单元&#xff1a; 1、Pod概念 Pod 是可以在 Kubernetes中创建和管理的、最小的可部署的计算单元。它由一组、一…

设计模式之静态代理

一些个人理解 顾名思义&#xff0c;就是代理一个对象。 那么&#xff0c;既然要代理一个东西&#xff0c;就要传入它吧? 【1】所以将代理对象当作属性【【2】往往通过构造方法传入被代理的目标对象】。 既然要代理&#xff0c;那必然要和代理对象拥有相同的功能吧? 所以实现了…

牛津大学xDeepMind 自然语言处理(1)

牛津大学xDeepMind 自然语言处理 Natural Language Processing 词向量与词汇语义学 Word Vectors and Lexical Semantics 词语表示的基本问题与分布语义思想 传统词语表示&#xff08;如独热向量&#xff09;存在稀疏、正交、语义弱的问题&#xff0c;无法表达语义相似性。分布…

StarRocks数据库集群的完整部署流程

目录 依赖环境 下载安装包 部署FE 部署BE 搭建集群 停止集群 依赖环境 详见&#xff1a;StarRocks 部署&#xff1a;依赖环境-CSDN博客 下载安装包 在官方网站下载安装包&#xff1a;StarRocks 部署FE 创建元数据目录。 mkdir -p <meta_dir> 修改 FE 配置文件 f…

简单的 VSCode 设置

以下是我使用的vscode设置。虽然有些主观&#xff0c;但很实用。1 主题。我放弃了那些炫酷的主题。我选择了Tokyo Night (Storm)。理由是&#xff1a;它平静、赏心悦目&#xff0c;并且与代码形成了美丽的对比&#xff0c;却又不显得刺眼。2. 字体。我切换到了 JetBrains Mono …

Rust 条件语句

Rust 条件语句 在编程语言中&#xff0c;条件语句是程序流程控制的重要组成部分。Rust 作为一种系统编程语言&#xff0c;其条件语句的设计简洁而强大。本文将详细介绍 Rust 中的条件语句&#xff0c;包括其语法、用法以及一些高级特性。 1. 基本条件语句 Rust 中的基本条件语句…

【Java EE进阶 --- SpringBoot】初识Spring(创建SpringBoot项目)

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java, Java EE初阶&#xff0c; Java数据结构 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励…

脑潜在进展:基于潜扩散模型的三维脑磁共振成像个体时空疾病进展研究|文献速递-深度学习人工智能医疗图像

Title题目Brain Latent Progression: Individual-based spatiotemporal diseaseprogression on 3D Brain MRIs via latent diffusion脑潜在进展&#xff1a;基于潜扩散模型的三维脑磁共振成像个体时空疾病进展研究01文献速递介绍神经退行性疾病是现代医疗保健领域最紧迫的挑战之…

专题:2025AI技术应用与发展报告|附600+份报告PDF、数据仪表盘汇总下载

原文链接&#xff1a;https://tecdat.cn/?p43632 当企业管理者看着后台65%的任务被AI自动分配&#xff0c;却仍在为下周的营销方案熬夜改稿时&#xff0c;一个现实的矛盾浮出水面&#xff1a;AI到底能帮企业做什么&#xff1f; 2025年&#xff0c;算法研发投入占企业AI预算的…

【笔记】扩散模型(一一):Stable Diffusion XL 理论与实现

论文链接&#xff1a;SDXL: Improving Latent Diffusion Models for High-Resolution Image Synthesis 官方实现&#xff1a;Stability-AI/generative-models 非官方实现&#xff1a;huggingface/diffusers Stable Diffusion XL (SDXL) 是 Stablility AI 对 Stable Diffusion 进…

学习安卓APP开发,10年磨一剑,b4a/Android Studio

学习安卓APP开发 记得上次学APP都是在2016年前了&#xff0c;一晃就过去了10年。 当时用ANDROID studio打开一个空项目和编绎分别用了300秒&#xff0c;一下就用了10分钟。 后来买了一台一万多的电脑&#xff0c;CPU换成了I5 8600K 4.2GHZ*6核&#xff0c;再加上M2固态硬盘。 编…

调试技巧(vs2022 C语言)

调试之前首先要保证我们的脑袋是清晰的&#xff0c;我们调试的过程主要是看代码有没有按照我们的想法去运行调试最常使用的几个快捷键F5启动调试&#xff0c;经常用来直接跳到下一个断点处&#xff08;F5通常和F9配合使用&#xff0c;打了断点按F5程序可以直接运行到断点处&…

MySQL深度理解-Innodb底层原理

1.MySQL的内部组件结构大体来说&#xff0c;MySQL可以分为Server层和存储引擎层两部分。2.Server层Server层主要包括连接器、查询缓存、分析器、优化器和执行器等&#xff0c;涵盖MySQL的大多数核心服务功能&#xff0c;以及所有的内置函数&#xff08;如日期、时间、数据和加密…

QFtp在切换目录、上传文件、下载文件、删除文件等一系列操作时,如何按照预期操作指令顺序执行

FTP服务初始化时&#xff0c;考虑到重连、以及commandFinished信号信号执行完成置m_bCmdFinished 为true; void ICore::connectFtpServer() {if(g_pFile nullptr){g_pFile new QFile;}if(g_pFtp){g_pFtp->state();g_pFtp->abort();g_pFtp->deleteLater();g_pFtp n…

JavaSE高级-02

文章目录1. 多线程1.1 创建线程的三种方式多线程的创建方式一&#xff1a;继承Thread类多线程的创建方式二&#xff1a;实现Runnable接口多线程的创建方式三&#xff1a;实现Callable接口三种线程的创建方式对比Thread的常用方法1.2 线程安全线程同步方式一&#xff1a;同步代码…