CommonJS(CJS)和ESModule(ESM)有什么区别详解

 更新时间:2026年06月23日 09:39:18   作者:半岛@少年  
ES Modules(ESM)和CommonJS(CJS)是JavaScript中两种主要的模块系统,它们在语法、加载方式和运行时有显著差异,这篇文章主要介绍了CommonJS(CJS)和ESModule(ESM)有什么区别的相关资料,需要的朋友可以参考下

一:定义

  • CommonJS(CJS)非ECMA官方规范,用于NodeJS默认加载加载模块化方式,浏览器无法运行,使用**module.exports/require**导入模块文件。
  • ESModule(ESM):ES6(ECMA)官网标准,浏览器 + Node通用模块化规范,前端工程主流方案,使用**export/import**导入模块文件。

二:使用场景

1. 模块的导入导出

规范

导出

导入

CJS

module.exports = { a: 1, b: 2, ... }

exports.a = 1

const module = require("./xxx")
ESM

export const a = 1

export default = { a: 1, b: 2, ... }

import module from "./xxx" (静态、同步)

import ("./xxx") (动态、异步)

// CJS示例
// a.js
exports.num = 1
// index.js
const { num } = require('./a')

// ESM示例
// a.js
export let num = 1
// 静态导入(顶层专用)
import { num } from './a'
// 动态导入(任意位置,返回Promise)
import('./a').then(res=>{})

2. 加载顺序

# CJS:同步加载,会阻塞代码运行。require是普通函数,代码执行到当前行才会加载该文件,支持代码动态引入。

// CJS合法:if、for、函数内部任意位置写require
if(flag){
  const m = require('./mod1')
}else{
  const m = require('./mod2')
}

# ESM静态引入:编译时静态解析,提前写入全部模块路径,必须写在代码最顶层,代码同步加载。

// ESM 静态文件加载
// 默认 导入
import module from "./xxx"
// 命名 导入
import { module } from "./xxx"
// 全量导入
import  * as module from "./xxx"

# ESM动态引入:可以运行时异步加载,返回Promise,import()是ES内置函数,CJS/ESM环境都能识别,任意位置都能调用,用于路由懒加载、按需引入。

// ESM 动态导入
import("./xxx")

// Promise
import("./xxx").then(res => {
    // 业务代码
})

3. 导出值绑定:值拷贝 vs 实时绑定

# CJS:导出值的副本(浅拷贝),原模块变量变化不影响导入值

// c.js(CJS)
let count = 1
exports.count = count
exports.add = ()=>count++

// index.js(CJS)
const {count,add}=require('./c')
console.log(count) //1
add()
console.log(count) //1(拷贝快照,原变量变了不更新)

# ESM:导出实时引用绑定,原模块值变更,导入变量自动同步更新

// e.js(ESM)
export let count =1
export const add = ()=>count++

// index.js(ESM)
import {count,add} from './e'
console.log(count)//1
add()
console.log(count)//2(实时绑定,同步变化)

4. 静态优化能力(Tree-Shaking 关键)

# CJS无法 Tree-Shaking,运行时动态解析依赖,打包阶段无法剔除未使用代码,打包体积偏大。

# ESM支持 Tree-Shaking,编译时确定导入导出,webpack/rollup 可删除未被引入的export代码,精简打包产物。

5. 顶层 this 与内置变量

# CJS:每个模块被包装成闭包函数,顶层 this = module.exports;

# ESM:顶层 this = undefined,默认开启严格模式use strict

6. 模块缓存 & 循环依赖

# CJS第一次require加载后缓存module.exports,再次引入直接读缓存;循环依赖时返回未完成导出的空对象

# ESM:通过拓扑排序解析依赖,循环依赖拿到实时引用,不会返回空对象。

7. 跨规范互导规则

ESM import CJS:只能整体默认导入,无法单独解构 CJS 命名导出。

// cjs模块:module.exports={a:1,b:2}
import all from './cjs' //✅正确,all={a:1,b:2}
import {a} from './cjs' //❌报错,ESM不能解构CJS导出

CJS require ESM:Node 原生不支持同步require(ESM),直接报ERR_REQUIRE_ESM,只能用await import()异步引入。

三:使用场景总结

# CJS:适用于Node 后端服务、脚手架工具、老项目遗留代码;

# ESM:适用于前端 Vue/React 项目、浏览器原生模块化、新项目标准选型。

四:小结

  • CJS运行时同步加载、值拷贝、无TreeShaking;ESM编译时静态导入 + 动态import()异步、实时绑定、支持TreeShaking;
  • CJS用require/module.exports,ESM用import/export。
  • CJS环境不识别静态import,仅兼容import()动态导入。

到此这篇关于CommonJS(CJS)和ESModule(ESM)有什么区别的文章就介绍到这了,更多相关CJS和ESM区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Bootstrap Table使用整理(一)

    Bootstrap Table使用整理(一)

    基于 Bootstrap 的 jQuery 表格插件,通过简单的设置,就可以拥有强大的单选、多选、排序、分页,以及编辑、导出、过滤(扩展)等等的功能
    2017-06-06
  • layui 富文本赋值,取值,取纯文本值的实例

    layui 富文本赋值,取值,取纯文本值的实例

    今天小编就为大家分享一篇layui 富文本赋值,取值,取纯文本值的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • javascript奇异的arguments分析

    javascript奇异的arguments分析

    在 Javascript 的函数中有个名为 arguments 的类数组对象。它看起来是那么的诡异而且名不经传,但众多的 Javascript 库都使用着它强大的功能。所以,它的特性需要每个 Javascript 程序员去熟悉它。
    2010-10-10
  • 微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)

    微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)

    这篇文章主要介绍了微信小程序scroll-view左侧导航栏点餐功能实现,点击种类,滚动到锚点;滚动到锚点,种类选中,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • DEDECMS如何为文章添加HOT NEW标志图片

    DEDECMS如何为文章添加HOT NEW标志图片

    再用织梦建站的时候,常常需要要在列表页添加前两天的文章后面添加个new小图片,那么此功能是怎么实现的呢,下面通过本文给大家详解dedecms为文章添加HOT NEW标志图片,需要的朋友可以参考下
    2015-08-08
  • 实例讲解避免javascript冲突的方法

    实例讲解避免javascript冲突的方法

    这篇文章主要以实例的方式讲解了避免javascript冲突的方法,具有一定的参考价值,感兴趣的朋友可以参考一下
    2016-01-01
  • JavaScript图像延迟加载库Echo.js

    JavaScript图像延迟加载库Echo.js

    Echo 是一个独立的 JavaScript 懒加载图像的工具,快速、体积小(不足1k)和使用 HTML5 的 data- 属性,通过本文给大家介绍JavaScript图像延迟加载库Echo.js ,感兴趣的朋友一起学习吧
    2016-04-04
  • js实现上传图片预览的方法

    js实现上传图片预览的方法

    这篇文章主要介绍了js实现上传图片预览的方法,通过自定义函数结合onchange方法实现上传图片的预览功能,非常具有实用价值,需要的朋友可以参考下
    2015-02-02
  • javascript实现依次输入input自动定焦

    javascript实现依次输入input自动定焦

    这篇文章主要介绍了javascript实现依次输入input自动定焦的方法及示例代码,非常实用,这里推荐给小伙伴们
    2014-12-12
  • Layer+Echarts构建弹出层折线图的方法

    Layer+Echarts构建弹出层折线图的方法

    今天小编就为大家分享一篇Layer+Echarts构建弹出层折线图的方法,具有很的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09

最新评论