前言

如下图:

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. 洛谷P2845

    蓝题搜索,模拟上的细节稍微有点麻烦 #include<iostream> #include<utility> #include<vector> #include&l ...

  2. PowerBuilder编程新思维6:装饰(用最简单的方式做框架)

    To be, or not to be - that is the question. PowerBuilder编程新思维6:装饰(用最简单的方式做框架) 问题 这一章,是写得最艰难的一章,原因有四: ...

  3. php.ini文件与php.d

    `php.ini` 是 PHP 的主要配置文件,用于全局配置 PHP 的行为和功能.它包含了许多 PHP 的核心设置,如内存限制.错误报告级别.扩展加载等. `php.ini` 文件通常位于 PHP ...

  4. Vue禁止用户复制文案 + 兼容 IE

    vue必须要加载完才可以操作dom,或者在mounted和created时使用this.$nextTick方法,使dom生成后进行相关操作. created() { this.$nextTick(() ...

  5. [oeasy]python0069_帮助手册_pydoc_manual_document

    帮助手册 回忆上次内容   上次了解了注释 注释是为了让程序更可读 注释不会影响程序运行速度   注释分为两种 单行的 以#开头 不能是字符串当中的#   多行的 三个" 三个'     多 ...

  6. 可视化—gojs 超多超实用经验分享(四)

    目录 41.监听连线拖拽结束后的事件 42.监听画布的修改事件 43.监听节点被 del 删除后回调事件(用于实现调用接口做一些真实的删除操作) 44.监听节点鼠标移入移出事件,hover 后显示特定 ...

  7. ElementUI Dialog 结合Vue实现对话框body“二分”布局

    Dialog 结合Vue实现对话框body"二分"布局 需求描述 如下图, 把对话框body内容部分,分成上下两部分,其中上部分高度根据窗口大小动态调整,如果内容过多,则出现滚动条 ...

  8. CCF 无线网络

    题目原文 问题描述(题目链接登陆账号有问题,要从这个链接登陆,然后点击"模拟考试",进去找本题目) 试题编号: 201403-4 试题名称: 无线网络 时间限制: 1.0s 内存限 ...

  9. 【AppStore】IOS应用上架Appstore的一些小坑

    前言 上一篇文章写到如何上架IOS应用到Appstore,其中漏掉了些许期间遇到的小坑,现在补上 审核不通过原因 5.1.1 Guideline 5.1.1 - Legal - Privacy - D ...

  10. 我用Awesome-Graphs看论文:解读PowerGraph

    PowerGraph论文:<PowerGraph: Distributed Graph-Parallel Computation on Natural Graphs> 上次通过文章< ...