前言

如下图:

AMD与CMD的主要区别:

  • 1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.
  • 2. CMD 推崇依赖就近,AMD 推崇依赖前置。看代码:
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
var b = require('./b')
b.doSomething()
})
// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
b.doSomething()
})

AMD与CMD的其它区别可参考地址:https://www.zhihu.com/question/20351507

AMD

AMD规范可参考地址:https://github.com/amdjs/amdjs-api/wiki/AMD

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。

根据AMD规范,我们可以使用define定义模块,使用require调用模块,语法:

 define(id?, dependencies?, factory);
  • id: 定义中模块的名字;可选;如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字;
  • dependencies:依赖的模块;
  • factory:工厂方法,返回定义模块的输出值。

总结一段话:声明模块的时候指定所有的依赖dependencies,并且还要当做形参传到factory中,对于依赖的模块提前执行,依赖前置

例子1:

 define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
exports.verb = function() {
return beta.verb();
//Or:
return require("beta").verb();
}
});

例子2:

 define(["alpha"], function (alpha) {
return {
verb: function(){
return alpha.verb() + 2;
}
};
});

例子3:

   define({
add: function(x, y){
return x + y;
}
});

例子4:

define(function (require, exports, module) {
var a = require('a'),
b = require('b'); exports.action = function () {};
});

使用require函数加载模块:

require([dependencies],function(){});
  • 第一个参数是一个数组,表示所依赖的模块
  • 第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用.加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块

require()函数在加载依赖的函数的时候是异步加载的,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题

require(['alpha'],function(alpha){
alpha.verb ();
})

CMD

CMD规范参考地址:https://github.com/seajs/seajs/issues/242  CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。

define Function

define 是一个全局函数,用来定义模块。

define define(factory)

define 接受 factory 参数,factory 可以是一个函数,也可以是一个对象或字符串。

factory 为对象、字符串时,表示模块的接口就是该对象、字符串。比如可以如下定义一个 JSON 数据模块:

define({ "foo": "bar" });

也可以通过字符串定义模板模块:

define('I am a template. My name is {{name}}.');

factory 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数:requireexports 和 module

define(function(require, exports, module) {

  // 模块代码

});

define define(id?, deps?, factory)

define 也可以接受两个以上参数。字符串 id 表示模块标识,数组 deps 是模块依赖。比如:

define('hello', ['jquery'], function(require, exports, module) {

  // 模块代码

});

id 和 deps 参数可以省略。省略时,可以通过构建工具自动生成。

注意:带 id 和 deps 参数的 define 用法不属于 CMD 规范,而属于 Modules/Transport 规范。

define.cmd Object

一个空对象,可用来判定当前页面是否有 CMD 模块加载器:

if (typeof define === "function" && define.cmd) {
// 有 Sea.js 等 CMD 模块加载器存在
}

require Function

require 是 factory 函数的第一个参数。

require require(id)

require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口。

define(function(require, exports) {

  // 获取模块 a 的接口
var a = require('./a'); // 调用模块 a 的方法
a.doSomething(); });

require.async require.async(id, callback?)

require.async 方法用来在模块内部异步加载模块,并在加载完成后执行指定回调。callback 参数可选。

define(function(require, exports, module) {

  // 异步加载一个模块,在加载完成时,执行回调
require.async('./b', function(b) {
b.doSomething();
}); // 异步加载多个模块,在加载完成时,执行回调
require.async(['./c', './d'], function(c, d) {
c.doSomething();
d.doSomething();
}); });

注意:require 是同步往下执行,require.async 则是异步回调执行。require.async 一般用来加载可延迟异步加载的模块。

exports Object

exports 是一个对象,用来向外提供模块接口。

define(function(require, exports) {

  // 对外提供 foo 属性
exports.foo = 'bar'; // 对外提供 doSomething 方法
exports.doSomething = function() {}; });

除了给 exports 对象增加成员,还可以使用 return 直接向外提供接口。

define(function(require) {

  // 通过 return 直接提供接口
return {
foo: 'bar',
doSomething: function() {}
}; });

module Object

module 是一个对象,上面存储了与当前模块相关联的一些属性和方法。

module.id String

模块的唯一标识。

define('id', [], function(require, exports, module) {

  // 模块代码

});

上面代码中,define 的第一个参数就是模块标识。

module.exports Object

当前模块对外提供的接口。

传给 factory 构造方法的 exports 参数是 module.exports 对象的一个引用。只通过 exports 参数来提供接口,有时无法满足开发者的所有需求。 比如当模块的接口是某个类的实例时,需要通过 module.exports 来实现:

define(function(require, exports, module) {

  // exports 是 module.exports 的一个引用
console.log(module.exports === exports); // true // 重新给 module.exports 赋值
module.exports = new SomeClass(); // exports 不再等于 module.exports
console.log(module.exports === exports); // false });

CommonJS

CommonJS是服务器端模块的规范,Node.js采用了这个规范.Node.JS首先采用了js模块化的概念.
CommonJS定义的模块分为:模块引用(require)/ 模块定义(exports)/模块标识(module)

所有代码都运行在模块作用域,不会污染全局作用域。

模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。

模块加载的顺序,按照其在代码中出现的顺序。

//common.js
module.exports = function(a, b) {
return a-b
} let minus = require('./common.js') //文件相对路径
console.log(minus(5,4))
// 结果: 1

详细可以参考《阮一峰:CommonJS规范》

ES6

导出

ES6两种导出方式:

  1. 命名导出
  2. 默认导出

命名导出

// 写法1
export const name = 'calculator';
export const add = function (a,b) {
return a + b;
} // 写法2
const name = 'calculator';
const add = function (a,b) {
return a + b;
}
export {name, add};

在使用命名导出时,可以通过as关键字对变量重命名。如:

const name = 'calculator';
const add = function (a,b) {
return a + b;
}
export {name, add as getSum}; // 在导入时即为name 和 getSum

默认导出

export default {
name: 'calculator';,
add: function (a,b) {
return a + b;
}
};

导入

针对命名导出的模块,导入方式如下:

// calculator.js
const name = 'calculator';
const add = function (a,b) {
return a + b;
}
export {name, add}; // 一般导入方式
import {name, add} from './calculator.js'
add(2,3); // 通过as关键字对导入的变量重命名
import {name, add as calculateSum} from './calculator.js'
calculateSum(2,3); // 使用 import * as <myModule>可以把所有导入的变量作为属性值添加到<myModule>对象中,从而减少了对当前作用域的影响
import * as calculateObj from './calculator.js'
calculateObj.add(2,3);

对于默认导出来说,import后面直接跟变量名,并且这个名字可以自由指定,它指代了calculator.js中默认导出的值。从原理上可以这样理解:

import {default as myCalculator} from './calculator.js'

还有两种导入方式混合起来使用的例子,如下:

// index.js
import React, {Component} from 'react';

注:这里的React必须写在大括号前面,而不能顺序颠倒,否则会提示语法错误。

复合写法

在工程中,有时候需要把一个模块导入后立即导出,比如专门用来集合所有页面或组件的入口文件。此时可以采用复合形式的写法:

export {name, add } from './calculator.js'

复合写法只支持通过命名导出的方式暴露出来的变量,默认导出则没有对应的复合形式,只能将导入和导出拆分开。

import calculator from './calculator.js'
export default calculator;

UMD

UMD并不能说是一种模块标准,不如说它是一组模块形式的集合更准确。UMD的全称是Universal Module Definition,也就是通用模块标准。它的目标是使一个模块能运行在各种环境下,不论是CommonJS、AMD,还是非模块化的环境(当时ES6 Module还未被提出)

(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS之类的
module.exports = factory(require('jquery'));
} else {
// 浏览器全局变量(root 即 window)
root.returnExports = factory(root.jQuery);
}
}(this, function($) {
// 方法
function myFunc() {}; // 暴露公共方法
return myFunc; }));

详细可参考:《可能是最详细的UMD模块入门指南》《AMD , CMD, CommonJS,ES Module,UMD》

JS之AMD、CMD、CommonJS、ES6、UMD的使用笔记的更多相关文章

  1. FW: AMD, CMD, CommonJS和UMD

    javascript 我是豆腐不是渣 4月5日发布 推荐 2 推荐 收藏 32 收藏,486 浏览 今天由于项目中引入的echarts的文件太大,requirejs经常加载超时,不得不分开来加载ech ...

  2. AMD, CMD, CommonJS和UMD

    我的Github(https://github.com/tonyzheng1990/tonyzheng1990.github.io/issues),欢迎star 今天由于项目中引入的echarts的文 ...

  3. js模块系统 - amd|cmd|commonjs|esm|umd

    写过前端代码大概率听说过amd cmd umd commonjs esm这些名词, 想当初我第一次看到这些的时候, 人都麻了, 都是些啥啊. 后来我知道了, 这些都是js的模块规范. amd - 浏览 ...

  4. JS模块之AMD, CMD, CommonJS、UMD和ES6模块

    CommonJS 传送门 同步加载,适合服务器开发,node实现了commonJS.module.exports和require 判断commonJS环境的方式是(参考jquery源码): if ( ...

  5. AMD,CMD.CommonJs和UMD还有es6的模块化对比

    CommonJS CommonJS是服务器端模块的规范,Node.js采用了这个规范. 根据CommonJS规范,一个单独的文件就是一个模块.加载模块使用require方法,该方法读取一个文件并执行, ...

  6. AMD CMD commonJS es6

    看到很多人傻傻的分不清楚 AMD.CMD . commonJS . es6的区别,实际上这跟这几年前段技术的发展有很大的关系. 实际上这是JavaScript的模块化思想演进的一个过程. 最开始的时候 ...

  7. es6的模块化--AMD/CMD/commonJS/ES6

    , ); ); }) , )); }); , )); ; export { firstName, lastName, year }; // es6引用 import { firstName, last ...

  8. Amd,Cmd, Commonjs, ES6 import/export的异同点

    Amd,Cmd, Commonjs, ES6 import/export等均是模块化方案 1.Commonjs使用在Nodejs上,加载模块是同步的. 2.Amd是requirejs在推广过程中对模块 ...

  9. AMD/CMD/CommonJs到底是什么?它们有什么区别?

    知识点1:AMD/CMD/CommonJs是JS模块化开发的标准,目前对应的实现是RequireJs/SeaJs/nodeJs.   知识点2:CommonJs主要针对服务端,AMD/CMD主要针对浏 ...

  10. js模块化AMD/CMD

    JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?     模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题进行系统 ...

随机推荐

  1. 网易数帆内核团队:memory cgroup 泄漏问题的分析与解决

    memory cgroup 泄露是 K8s(Kubernetes) 集群中普遍存在的问题,轻则导致节点内存资源紧张,重则导致节点无响应只能重启服务器恢复:大多数的开发人员会采用定期 drop cach ...

  2. [oeasy]python0081_ANSI序列由来_终端机_VT100_DEC_VT选项_终端控制序列

    更多颜色 回忆上次内容 上次 首先了解了RGB颜色设置 可以把一些抽象的色彩名字 落实到具体的 RGB颜色 计算机所做的一切 其实就是量化.编码 把生活的一切都进行数字化 标准 是ANSI制定的 这个 ...

  3. 踩坑记录:windows11下使用 VS2022 和 PCL1.14.1 配置点云开发环境

    闲话不多说,具体在windows下下载PCL与解压pcl可以看https://www.yuque.com/huangzhongqing/pcl/这位大佬的文章,那我就具体说一下踩过点坑: 踩坑点1: ...

  4. iframe嵌入svg图片动态更改文本样式并进行缩放等功能实现拓扑图

    好久没更了,近期开发遇到的需求,抽空梳理一下~ 需求:实现一个复杂的拓扑图,图中元素的个数,以及各个参数内容是动态展示的. 于是让ui提供了对应的svg图片. 解决思路:使用iframe嵌入svg图片 ...

  5. docker 概念,安装,启动,运行

    docker概念,安装,启动,运行模式 docker的概念 镜像(image) 模板,可以通过模板来创建容器服务,tomcat镜像===>run==>tomacat01容器(提供服务),通 ...

  6. [rCore学习笔记 019]在main中测试本章实现

    写在前面 本随笔是非常菜的菜鸡写的.如有问题请及时提出. 可以联系:1160712160@qq.com GitHhub:https://github.com/WindDevil (目前啥也没有 批处理 ...

  7. systempath:Python开发者必备的文件与系统路径操作神器!

    systempath - 专业级的文件与系统路径操作库 English | 中文 systempath 是一个专为Python开发者设计的,高度专业化的文件与系统路径操作库.通过提供一套直观且功能强大 ...

  8. 【SpringBoot】02 概述

    [目标] - 什么是SpringBoot? 并不是新技术,只是一个Spring的加强 解脱XML配置,增加了新的注解,但是并不是新的内容 - 新型配置文件技术 YAML - 自动装配原理[了解即可,不 ...

  9. 【Ubuntu】下载安装 20.04.版本 桌面端

    下载 Download 这次的是直接在界面上下载的,我都不知道为什么怎么点到之前的版本去了 12.04.5远古版本界面怪难看的... [下载地址:点我访问] https://cn.ubuntu.com ...

  10. 美国小伙: "American Guy: Only communism can save America!"

    视频地址: https://www.youtube.com/watch?v=Y_WQnXFh8ss 2024大选在即,又是拜登对阵特朗普的旧日重现.在角逐谁的对手反对者更多的畸形内耗中,有一个名为 M ...