一篇搞定CJS,AMD,CMD,ESM

不知道有没有被缩写搞头疼过,为什么明明直接说全程就能明白的名词就要搞缩写。。。

以下是各模块化规范的对比分析,一张表直接理解:

特性 CommonJS AMD (RequireJS) CMD (Sea.js) ES6 Modules
加载方式 同步加载(服务器端) 异步加载(浏览器端) 异步加载(浏览器端) 静态加载(编译时确定依赖)
语法 require / module.exports define / require define / require import / export
依赖声明时机 动态依赖(运行时解析) 依赖前置(提前声明) 依赖就近(按需声明) 静态依赖(编译时解析)
模块执行时机 加载时执行 提前执行(依赖前置) 延迟执行(按需执行) 编译时加载,只执行一次
输出类型 值的拷贝(原始类型不受影响) 值的拷贝 值的拷贝 值的引用(实时绑定)
循环依赖处理 支持但可能导致部分加载 支持但需谨慎管理 支持但需谨慎管理 静态分析支持更好
适用环境 Node.js 浏览器端 浏览器端 浏览器 + Node.js(现代环境)
优缺点 ✅ 简单易用 ❌ 同步加载不适用浏览器 ✅ 异步加载优化性能 ❌ 依赖前置不够灵活 ✅ 依赖就近更灵活 ❌ 社区生态较小 ✅ 语言标准、静态优化 ❌ 旧环境需转译

详细解释及代码示例

1. CommonJS

  • 场景:Node.js 的默认模块系统。

  • 特点

    • 同步加载模块,模块在首次 require 时加载并执行。
    • 输出的是值的拷贝(原始类型为拷贝,对象为引用)。
    javascript 复制代码
    // math.js
    let counter = 0;
    const add = () => counter++;
    module.exports = { counter, add };
    
    // main.js
    const { counter, add } = require('./math');
    add();
    console.log(counter); // 输出 0(counter 是拷贝值)

2. AMD (Asynchronous Module Definition)

  • 场景:浏览器端异步加载(如 RequireJS)。

  • 特点

    • 依赖前置,模块加载后立即执行。
    javascript 复制代码
    // 定义模块
    define(['dep1', 'dep2'], function(dep1, dep2) {
      return { method: () => dep1.doSomething() };
    });
    
    // 使用模块
    require(['moduleA'], function(moduleA) {
      moduleA.method();
    });

3. CMD (Common Module Definition)

  • 场景:浏览器端(如 Sea.js),强调按需加载。

  • 特点

    • 依赖就近,模块使用时才加载。
    javascript 复制代码
    define(function(require, exports, module) {
      const dep1 = require('dep1'); // 按需加载
      exports.method = () => dep1.doSomething();
    });

4. ES6 Modules

  • 场景:现代浏览器和 Node.js(需配置)。

  • 特点

    • 静态分析,编译时确定依赖。
    • 输出值的引用(实时绑定)。
    javascript 复制代码
    // math.js
    export let counter = 0;
    export const add = () => counter++;
    
    // main.js
    import { counter, add } from './math.js';
    add();
    console.log(counter); // 输出 1(counter 是引用)

再废话一次,核心区别总结

  1. 加载机制

    • CommonJS 同步加载,适合服务器。
    • AMD/CMD 异步加载,适合浏览器。
    • ES6 静态加载,通用且支持优化。
  2. 模块定义与依赖管理

    • CommonJS/AMD/CMD 动态依赖,ES6 静态依赖。
    • AMD 依赖前置,CMD 依赖就近,ES6 依赖声明在顶部。
  3. 值的传递

    • CommonJS/AMD/CMD 输出值拷贝,ES6 输出实时引用。
  4. 生态与未来

    • ES6 是语言标准,支持 Tree-shaking 等优化。
    • CommonJS 主导 Node.js 生态,AMD/CMD 逐渐被替代。

在实际应用中建议大家

  • 现代项目 :优先使用 ES6 Modules,结合 Webpack/Rollup 打包兼容旧环境。
  • Node.js 开发:CommonJS 为主,逐步迁移到 ES6。
  • 遗留浏览器项目:AMD 或 CMD 过渡,最终转向 ES6 + 打包工具。
相关推荐
蓑笠翁0011 小时前
Python异步编程入门:从同步到异步的思维转变
linux·前端·python
程序员小杰@3 小时前
✨WordToCard使用分享✨
前端·人工智能·开源·云计算
larntin20023 小时前
vue2开发者sass预处理注意
前端·css·sass
Enti7c3 小时前
利用jQuery 实现多选标签下拉框,提升表单交互体验
前端·交互·jquery
SHUIPING_YANG4 小时前
在Fiddler中添加自定义HTTP方法列并高亮显示
前端·http·fiddler
互联网搬砖老肖4 小时前
Web 架构之前后端分离
前端·架构
水银嘻嘻5 小时前
web 自动化之 selenium+webdriver 环境搭建及原理讲解
前端·selenium·自动化
寧笙(Lycode)5 小时前
为什么使用Less替代原始CSS?
前端·css·less
m0_zj5 小时前
57.[前端开发-前端工程化]Day04-webpack插件模式-搭建本地服务器
前端·webpack·node.js
GoFly开发者5 小时前
GoFly企业版框架升级2.6.6版本说明(框架在2025-05-06发布了)
前端·javascript·vue.js