AMD(Modules/Asynchronous-Definition)、CMD(Common Module Definition)的区别

本文对比了AMD和CMD两种JavaScript模块加载方式的主要差异。AMD推崇依赖前置且依赖项需在定义之初声明;而CMD则支持按需加载依赖,允许开发者将依赖声明分散在代码各处,更利于实现模块化和代码组织。

1:对于依赖

AMD是提前执行,CMD是延迟执行。

从requireJS 2.0开始CDM改成延迟执行(根据写法不一样,处理方式也不一样)。

CMD推崇懒加载 as lazy as possible.

2:对于依赖AMD推崇前置,CMD推崇依赖前置。

从列子看看区别吧!

// CMD

define(function(require, exports, module) {
    var a = require('./a')
    a.doSomething()
    // 此处略去 100 行
    var b = require('./b') // 依赖可以就近书写
    b.doSomething()
    // ...
})

// AMD

define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
    a.doSomething()
    // 此处略去 100 行
    b.doSomething()
    // ...
})

<think>我们被要求解释CommonJS、AMDCMD这三种前端模块化规范。需要分别说明它们的定义、特点、使用场景和代码示例,并在最后提出相关问题。 注意:回答必须包含3-5个相关问题,且以“§§相关问题§§”开头。 结构安排: 1. 分别介绍CommonJS、AMDCMD,包括它们的背景、特点、代码示例和适用环境。 2. 对比它们的差异(同步/异步,服务端/浏览器端等)。 3. 最后提出相关问题。 注意:由于用户要求用中文,且需要按照示例格式,末尾必须有问题部分。</think>### CommonJS、AMDCMD 模块化规范详解 #### 核心概念对比 ```mermaid graph LR A[模块化规范] --> B[CommonJS] A --> C[AMD] A --> D[CMD] B --> E[同步加载] C --> F[异步加载] D --> G[延迟执行] ``` #### 规范特性对比表 | **特性** | **CommonJS** | **AMD (RequireJS)** | **CMD (SeaJS)** | |------------------|----------------------------|---------------------------|---------------------------| | **适用环境** | Node.js 服务端 | 浏览器环境 | 浏览器环境 | | **加载方式** | 同步加载 | 异步加载 | 异步加载 | | **执行时机** | 运行时加载 | 提前执行 | 延迟执行(按需执行) | | **代表库** | Node.js 原生支持 | RequireJS | SeaJS | | **依赖声明** | 运行时解析 | 依赖前置 | 依赖就近 | | **代码示例** | ```js<br>const fs = require('fs');<br>module.exports = {...};``` | ```js<br>define(['dep1','dep2'],<br>function(d1,d2){<br> return {...};<br>});``` | ```js<br>define(function(require, exports, module){<br> const dep1 = require('./dep1');<br> module.exports = {...};<br>});``` | #### CommonJS 深度解析 **核心机制:** ```javascript // 模块定义 (math.js) function add(a, b) { return a + b; } module.exports = { add }; // 模块使用 (main.js) const math = require('./math'); console.log(math.add(2, 3)); // 5 ``` **特点:** - 同步加载导致阻塞(不适合浏览器) - 模块缓存机制(避免重复加载) - `module.exports` 和 `exports` 区别: ```javascript exports = module.exports = {}; // 初始指向同一对象 exports.name = 'test'; // 有效 exports = { value: 1 }; // 无效!切断了引用关系 ``` #### AMD (Asynchronous Module Definition) **RequireJS 实现:** ```html <!-- 浏览器引入 --> <script data-main="scripts/main" src="require.js"></script> ``` **模块定义:** ```javascript // 定义依赖前置的模块 define(['jquery', 'lodash'], function($, _) { const filterData = (arr) => _.filter(arr, item => item.active); return { render: function(data) { $('#list').html(filterData(data).join(',')); } }; }); // 动态加载 require(['math'], function(math) { alert(math.add(10, 20)); }); ``` **核心特点:** - 并行加载所有依赖 - 执行顺序不保证(依赖回调顺序) - 配置路径别名: ```javascript require.config({ paths: { 'jquery': 'https://cdn.example/jquery.min' } }); ``` #### CMD (Common Module Definition) **SeaJS 实现:** ```javascript // 模块定义 (兼容写法) define(function(require, exports, module) { // 依赖就近声明 const dep1 = require('./dep1'); const dep2 = require('./dep2'); // 导出接口 exports.action = function() { return dep1.process() + dep2.format(); }; // 完整导出替换 module.exports = { ... }; }); ``` **核心优势:** 1. **按需执行**:依赖模块使用时才执行 ```javascript if (condition) { const optional = require('./optional'); // 条件加载 } ``` 2. **依赖就近**:提升代码可读性 3. **同步写法**:保持编码习惯 #### 规范演进与现状 ```mermaid timeline title 模块化规范演进时间线 2009 : CommonJS 诞生(Node.js) 2011 : AMD 规范发布(RequireJS) 2011 : CMD 规范发布(SeaJS) 2015 : ES Modules 成为标准 2020+: ESM 原生浏览器支持普及 ``` **现代工程化方案:** - Webpack/Rollup 支持混合打包 - 兼容方案: ```javascript // 同时支持 CommonJS 和 ES Module import ES from './esm.js'; const Common = require('./cjs.js'); ``` **最佳实践建议:** 1. 新项目首选 ES Modules 2. 老项目改造: ```javascript // 从 CMD/AMD 迁移到 ESM import { func } from './old-module.js'; ``` 3. 工具库提供多格式输出: ```json // package.json { "main": "dist/common.js", // CommonJS "module": "dist/esm.js" // ES Module } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值