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

ES6和CommonJS模块区别

ES6 模块(ESM)和 CommonJS 是 JavaScript 中两种主要的模块规范,它们在设计理念、语法和行为上有显著区别。以下是两者的核心差异:

1. 语法规范与用途

  • ES6 模块(ESM)
    是 ECMAScript 2015 标准化的模块系统,适用于浏览器和 Node.js(需显式启用),是 JavaScript 官方模块规范。
    核心关键字:exportimportexport default

  • CommonJS
    是 Node.js 原生的模块规范,主要为服务器端设计,早期用于解决 Node.js 中的模块依赖问题。
    核心关键字:module.exportsexportsrequire()

2. 导出 / 导入语法

操作

ES6 模块(ESM)

CommonJS

默认导出

export default { ... }

module.exports = { ... }

命名导出

export const a = 1; export function f() {}

exports.a = 1; exports.f = function() {}

导入默认

import obj from './module.js'

const obj = require('./module.js')

导入命名

import { a, f } from './module.js'

const { a, f } = require('./module.js')

3. 加载时机与方式

  • ES6 模块:静态加载

    • 导入和导出语句在代码解析阶段执行(编译时加载),而非运行时。

    • 导入路径必须是静态字符串(不能动态拼接)。

    • 支持 import() 动态导入(返回 Promise)。

    示例:

    javascript

    运行

    --javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown
    // 静态导入(解析时执行)
    import { utils } from './tools.js';// 动态导入(运行时执行)
    import('./tools.js').then(module => { ... });
    
  • CommonJS:动态加载

    • 导入(require())在代码运行阶段执行,支持动态路径。

    • 模块加载是同步的(Node.js 中对本地模块有缓存优化)。

    示例:

    javascript

    运行

    --javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown
    // 支持动态路径
    const path = './tools.js';
    const utils = require(path);
    

4. 模块输出的本质

  • ES6 模块:值的引用

    • 导出的是值的只读引用,模块内部值变化时,导入方会同步更新。

    • 导入的变量是只读的(不能重新赋值)。

    示例:

    javascript

    运行

    --javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown
    // module.js
    export let count = 0;
    export function increment() { count++; }// main.js
    import { count, increment } from './module.js';
    increment();
    console.log(count); // 输出 1(跟随模块内部变化)
    
  • CommonJS:值的拷贝

    • 导出的是值的拷贝(对象导出的是引用地址的拷贝),模块内部值变化不影响导入方。

    • 导入的变量可以重新赋值。

    示例:

    javascript

    运行

    --javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown
    // module.js
    let count = 0;
    module.exports = {count,increment: () => { count++; }
    };// main.js
    const { count, increment } = require('./module.js');
    increment();
    console.log(count); // 输出 0(拷贝的值未更新)
    

5. 循环依赖处理

  • ES6 模块
    由于静态解析,模块在加载时会先创建「模块记录」,循环依赖时能正确引用未完全初始化的模块(返回部分导出值)。

  • CommonJS
    循环依赖时,会返回模块当前已执行部分的导出值(可能是不完整的),依赖后续执行补充。

6. 顶层 this 指向

  • ES6 模块:顶层 this 为 undefined

  • CommonJS:顶层 this 指向当前模块的 module.exports

7. 使用场景

  • ES6 模块

    • 浏览器环境(原生支持,需在 <script type="module"> 中使用)。

    • 现代前端工程(Vue、React 项目,通过 Webpack/Vite 打包)。

    • Node.js 13.2+(需在 package.json 中设置 "type": "module")。

  • CommonJS

    • Node.js 环境(默认模块系统)。

    • 早期 Node.js 生态的库(如 Express 中间件)。

总结

特性

ES6 模块(ESM)

CommonJS

加载时机

解析时(静态)

运行时(动态)

输出本质

值的引用(只读)

值的拷贝(可修改)

循环依赖处理

基于模块记录(更可靠)

基于执行状态(可能不完整)

适用环境

浏览器 + 现代 Node.js

Node.js 原生

动态导入支持

import()(返回 Promise)

require() 天然支持


现代前端开发以 ES6 模块为主,而 CommonJS 主要用于 Node.js 后端开发。在实际项目中,两者可通过打包工具(如 Webpack)相互兼容。

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

相关文章:

  • GNU Make | C/C++项目自动构建入门
  • DevOps运维与开发一体化及Kubernetes运维核心详解
  • Aurobay EDI 需求分析:OFTP2 与 EDIFACT 驱动的汽车供应链数字化
  • DataAgent技术解析:数据智能的未来之路
  • LangGraph 上下文工程权威指南:构建智能、感知、有记忆的 AI 代理
  • Ubuntu平台查看.gz格式压缩文件内容以及利用grep命令过滤搜索内容
  • 《浪浪山小妖怪》知识竞赛来袭!测测你是几级影迷?
  • RL【1】:Basic Concepts
  • 情况三:已经 add ,并且也 commit 了
  • 机器人控制器开发(整体架构2 Lerobot介绍)
  • 佛山体彩第二届唱享之夜浪漫收官, 七夕音乐派对全场大合唱!
  • 使用 Gulp + Webpack 打造一个完整的 TypeScript 库构建流程
  • 社区医疗健康管理系统的设计与实现-(源码+LW+可部署)
  • Linux92 shell:倒计时,用户分类
  • [re_2] rpc|http|nginx|protobuf|
  • HBuilder X 4.76 开发微信小程序集成 uview-plus
  • 【Linux我做主】进程退出和终止详解
  • C++编程语言:标准库:第37章——正则表达式(Bjarne Stroustrup)
  • 拷打字节面试官之-吃透c语言-哈希算法 如何在3面拷打字节cto 3万行算法源码带你吃透算法面试所有考题
  • 【完整源码+数据集+部署教程】鸡粪病害检测系统源码和数据集:改进yolo11-bifpn-SDI
  • 前端开发中经常提到的iframe、DOM是什么?
  • WPF中的DataContext以及常见的绑定方式
  • windows下wsl2 ubuntu开发配置
  • 破解人事管理非标化困境:启效云低代码如何助力业务突围?
  • 为什么同步是无线通信的灵魂?WiFi 与 5G 帧结构中的关键技术
  • 创建一个只能直接构造和销毁,但不能被复制和移动的基类
  • burpsuite使用之CaA神器使用
  • 2025年企业级数据服务API平台大全和接入指南
  • Text2SQL与DataAgent技术深度对比与实践指南
  • Java集合源码解析之LinkedList