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

CommonJS 与 ESM 的模块规范

CommonJS 与 ESM 全面对比:原理、区别及项目坑点

一、定义

CommonJS(简称 CJS)

  • Node.js 早期自己发明的模块规范

  • 专为服务端设计

  • 浏览器原生不支持

  • 后缀 .js 默认就是 CJS(package.json 没有 type:module

ESM(ES Module)

  • JavaScript 官方语言标准

  • ES6 推出

  • 浏览器、Node.js 统一标准

  • 项目 package.json 写了:

    "type": "module"
    

    整个项目所有 .js 文件 强制变成 ESM


二、核心语法对比

1. 导入导出

CommonJS

// 导出
module.exports = { name: "张三" };// 导入
const cfg = require("./config.js");

ESM

// 导出
export default { name: "张三" };// 导入
import cfg from "./config.js";

三、最关键 7 大区别(必须记住)

1. 语法不同

  • CJS:require / module.exports

  • ESM:import / export

2. 有没有缓存

CommonJS

  • require 加载模块会缓存

  • 可以手动清缓存:

    delete require.cache[路径]
    

ESM

  • import 也会缓存,而且不让你清缓存

  • **没有 require.cache 给你用

  • 想热更新配置,只能:
    读文件文本 → vm 执行

3. 有没有 dirname /filename

CommonJS

自带:

console.log(__dirname); 
//D:\myCode\pqc-reader 「文件夹路径」console.log(__filename);
//D:\myCode\pqc-reader\config.js 「完整绝对路径 + 文件名」

ESM

没有!必须自己手动算:

import { fileURLToPath } from 'url';
import path from 'path';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
//import.meta.url => 当前 JS 文件的地址(文件网址file:///D:/myCode/...)
// fileURLToPath => 把上面的 “文件网址” 转成 “电脑正常路径”
//path.dirname = > 拿到这个文件所在的 “文件夹路径”

4. 能不能用顶层 await

CommonJS

不支持,只能在函数里用 async

ESM

支持顶层 await

const cfg = await loadConfig();

5. 加载方式

CommonJS

同步加载
适合服务端本地文件

ESM

异步加载
设计给浏览器用,Node 也兼容

6. 文件后缀规则

CommonJS

导入可以省略后缀:

require("./config");

ESM

必须写全后缀

import cfg from "./config.js"; // 必须 .js

7. 浏览器支持

CommonJS

浏览器完全不认识,必须打包(webpack/vite)

ESM

浏览器原生直接支持

<script type="module" src="index.js"></script>

总结:

最简单记忆口诀
  • CommonJS:Node 老规矩,用 require,有 __dirname,能清缓存,同步加载

  • ESM:官方新标准,用 import,无 __dirname,不能清缓存,支持顶层 await,前后端通用


http://www.jsqmd.com/news/816126/

相关文章:

  • 解决跨平台表情符号显示不一致的Noto Emoji架构设计与性能优化
  • 在VS Code中集成Cppcheck与MISRA-C:打造实时嵌入式代码质量守护
  • 基于Go的ChatGPT共享服务扩展:快速搭建企业级AI应用平台
  • 今天给大家介绍一个Vue 的网站组件库
  • Midjourney 120胶片风格失效诊断手册(颗粒失真/色温漂移/动态压缩异常全解)
  • 免费获取A股行情数据的终极Python解决方案:MOOTDX完整指南
  • PyGPT:聚合多模型与RAG的桌面AI助手,打造本地化智能工作流
  • React + TypeScript + Vite 构建 Bento 网格生成器:从拖拽交互到 Canvas 导出
  • 重卡充电桩怎么挑选?2026年五大品牌测评 - 科技焦点
  • AnyKernel3实战指南:三步打造Android内核自动化部署方案
  • 从仿真到代码:基于Simulink的双向交错CCM图腾柱PFC系统建模与MBD实践
  • AntiDupl.NET:完全指南 - 智能图片去重工具高效清理重复图片实战教程
  • 对于指定车模组别,我是希望能够自制
  • NotebookLM视觉提示工程终极手册:12类prompt模板+37个真实Notebook案例(含GitHub可运行源码)
  • 如何用novel-downloader构建个人数字图书馆:小说下载器完全指南
  • 保姆级教程:用迪文DMG80480C070_03WTC串口屏的RAM变量和描述指针,实现动态UI交互
  • 如何加速下载与捕获视频:Xtreme Download Manager 完全指南
  • 3分钟掌握NCM解密:Windows图形化工具完全指南
  • 2026年5月塑料托盘厂家推荐指南:防潮塑料托盘,双面塑料托盘,出口专用塑料托盘,货架塑料托盘公司优选! - 品牌鉴赏师
  • GT-SUITE浮动许可利用率低:软件许可浪费,回收再分配
  • CircuitPython嵌入式开发实战:从引脚访问到IPv6网络通信
  • 用STM32F407给GC9A01圆形屏做个触摸画板:CST816D驱动避坑与坐标处理实战
  • 3分钟极简教程:免费开源视频下载插件VideoDownloadHelper完全指南
  • ElevenLabs非正式语音合成全链路拆解(情绪权重矩阵×声学特征映射表×实时pitch抖动算法)
  • Zotero引用统计插件终极指南:一键获取学术论文引用数据
  • 高效虚拟显示器终极指南:ParsecVDisplay完整解决方案
  • 你的Obsidian笔记,值得拥有更好的外观吗?
  • 别再死记硬背公式了!带你用‘小偷分金币’的故事彻底理解巴什博弈(Bash Game)
  • 保姆级教程:在Ubuntu 20.04上为TDA4VM搭建Linux+RTOS双系统开发环境(含SDK 08.02.00下载与编译避坑指南)
  • 构建跨平台Qt5远程编译环境:Docker+SSH+Rsync实战指南