UMD 是 JavaScript 模块的通用模块定义模式。这些模块可能在任何中央工作,无论是在客户端、服务器还是其余中央。
UMD 模式通常试图提供与当今最风行的脚本加载器(例如 RequireJS 等)的兼容性。 在许多状况下,它应用 AMD 作为根底,并增加了非凡的外壳来解决 CommonJS 兼容性。
所以首先要理解 AMD.
AMD
AMD 代表异步模块定义(Asynchronous Module Definition). 它是 CommonJS (CJS) 标准的替代品。
API 指定了一种定义模块的机制,以便能够异步加载模块及其依赖项。 这特地实用于模块的同步加载会导致性能、可用性、调试和跨域拜访问题的浏览器环境。
AMD 库公开了一个全局定义函数,其 footprint 为:
define(modulename?,[dependencyA?, dependencyB?, …], function (objectA, objectB, …) {... var myExportedObj = function() { … } return myExportedObj;});
CommonJS
CommonJS 是一个我的项目,其指标是为浏览器之外的 JavaScript 指定一个生态系统(例如,在服务器上或本地桌面应用程序)。
服务器端 JavaScript 曾经存在很长时间了,并且可能提供一些与其余语言相比独特而乏味的劣势,因为客户端和服务器都应用雷同的语言。
可怜的是,服务器端 JavaScript 十分扩散。拜访文件的脚本在 rhino 和 V8 上未经批改就无奈应用。 Spidermonkey 和 JavaScriptCore 不能以雷同的形式加载附加模块。 JavaScript Web 框架与其解释器密切相关,并且常常被迫创立一堆 Python、Ruby 和 Java 程序员认为天经地义的 API。
该项目标指标是创立一个规范库,最终容许 Web 开发人员在任意数量的 Web 框架和工具中进行抉择,并在最适宜其应用程序的平台上运行该代码。
例如, foo.js 在同一目录中加载模块 circle.js。
const circle = require('./circle.js');console.log(`The area of a circle of radius 4 is ${circle.area(4)}`);
circle.js:
const PI = Math.PI;exports.area = function (r) { return PI * r * r;};exports.circumference = function (r) { return 2 * PI * r;};
模块 circle.js 曾经导出了函数 area(..) 和 circle(..)。 要将函数和对象增加到模块的根目录,您能够将它们增加到非凡的导出对象。
模块本地的变量将是公有的,就像模块被包装在一个函数中一样。 在这个例子中,变量 PI 是 circle.js 公有的。
如果您心愿模块导出的根是一个函数(例如构造函数),或者如果您想在一次调配中导出一个残缺的对象而不是一次构建一个属性,请将其调配给 module.exports 而不是 exports.
例子:
const square = require('./square.js');var mySquare = square(2);console.log(`The area of my square is ${mySquare.area()}`);
square.js 的实现:
// Assigning to exports will not modify module, must use module.exportsmodule.exports = function (width) { return { area: function () { return (width * width); } };}
咱们来单步调试一个理论例子来加深了解:
上图是一个自执行函数,两个输出参数 global 和 factory 别离传入了 this 和 function(exports)...
要导出的函数 log 的实现体,只是一个简略的 console.log.
上图这个 require 其实是 Node.js 外部实现:
以后 module 是 local.js 即 node 命令启动的 module,冀望加载的 是 log.js:
从 module 的 paths 数组里就能看出 Node.js 解析 module 的门路:从以后 module 所在的文件夹登程,始终回溯到 c 盘根目录下的 node_modules
log.js 的 paths:
load 之前先 compile:
第 1157 行的代码地位,变量 content 的内容就是 log.js 文件的内容:
compile 的逻辑就是执行 log.js 里的代码:
在这个上下文里,factory 指向的就是下图绿色高亮的函数:
define 为 undefined,所以进入 else 分支:
此处把 log 函数写入到 exports 对象的 log 属性里:
而后在咱们的利用代码里,就能够应用导出的 log 函数了:
更多Jerry的原创文章,尽在:"汪子熙":