javascript
CommonJS/AMD/CMD/UMD
為什么會有這幾種模式?
起源:Javascript模塊化
模塊化就是把復雜問題分解成不同模塊,這樣可維護性高,從而達到高復用,低耦合。
1.Commonjs
CommonJS是服務器端模塊的規范,Node.js采用了這個規范
根據CommonJS規范,一個單獨的文件就是一個模塊。加載模塊使用require方法,該方法讀取一個文件并執行,最后返回文件內部的exports對象。
// foobar.js
?
//私有變量
var test = 123;
?
//公有方法
function foobar () {
?
? ? this.foo = function () {
? ? ? ? // do someing ...
? ? }
? ? this.bar = function () {
? ? ? ? //do someing ...
? ? }
}
?//exports對象上的方法和變量是公有的
var foobar = new foobar();
exports.foobar = foobar;
?
//require方法默認讀取js文件,所以可以省略js后綴
var test = require('./boobar').foobar;
test.bar();
2.AMD和RequireJS
AMD是"Asynchronous Module Definition"的縮寫,意思就是"異步模塊定義".
AMD設計出一個簡潔的寫模塊API:
define(id?, dependencies?, factory);
第一個參數 id 為字符串類型,表示了模塊標識,為可選參數。若不存在則模塊標識應該默認定義為在加載器中被請求腳本的標識。如果存在,那么模塊標識必須為頂層的或者一個絕對的標識。
第二個參數,dependencies ,是一個當前模塊依賴的,已被模塊定義的模塊標識的數組字面量。
第三個參數,factory,是一個需要進行實例化的函數或者一個對象。
? 定義無依賴的模塊
?
define( {
? ? add : function( x, y ){
? ? ? ? return x + y ;
? ? }
} );
?
? 定義有依賴的模塊
?
define(["alpha"], function( alpha ){
? ? return {
? ? ? ? verb : function(){
? ? ? ? ? ? return alpha.verb() + 1 ;
? ? ? ? }
? ? }
});
?
? 定義數據對象模塊
?
define({
? ? users: [],
? ? members: []
});
?
?? 具名模塊
?
define("alpha", [ "require", "exports", "beta" ], function( require, exports, beta ){
? ? export.verb = function(){
? ? ? ? return beta.verb();
? ? ? ? // or:
? ? ? ? return require("beta").verb();
? ? }
});
?
? 包裝模塊
?
define(function(require, exports, module) {
? ? var a = require('a'),
? ? ? ? ? b = require('b');
?
? ? exports.action = function() {};
} );
?
不考慮多了一層函數外,格式和Node.js是一樣的:使用require獲取依賴模塊,使用exports導出API。
除了define外,AMD還保留一個關鍵字require。require 作為規范保留的全局標識符,可以實現為 module loader,也可以不實現。
?
模塊加載
?
require([module], callback)
AMD模塊化規范中使用全局或局部的require函數實現加載一個或多個模塊,所有模塊加載完成之后的回調函數。
其中:
[module]:是一個數組,里面的成員就是要加載的模塊;
callback:是模塊加載完成之后的回調函數。
例如:加載一個math模塊,然后調用方法 math.add(2, 3);
require(['math'], function(math) {
math.add(2, 3);
});
?
3.RequireJS
RequireJS 是一個前端的模塊化管理的工具庫,遵循AMD規范,它的作者就是AMD規范的創始人 James Burke。所以說RequireJS是對AMD規范的闡述一點也不為過。
RequireJS 的基本思想為:通過一個函數來將所有所需要的或者說所依賴的模塊實現裝載進來,然后返回一個新的函數(模塊),我們所有的關于新模塊的業務代碼都在這個函數內部操作,其內部也可無限制的使用已經加載進來的以來的模塊。
?
<script data-main='scripts/main' src='scripts/require.js'></script>
?
那么scripts下的main.js則是指定的主代碼腳本文件,所有的依賴模塊代碼文件都將從該文件開始異步加載進入執行。
define用于定義模塊,RequireJS要求每個模塊均放在獨立的文件之中。按照是否有依賴其他模塊的情況分為獨立模塊和非獨立模塊。
? 獨立模塊,不依賴其他模塊。直接定義:
define({
? ? method1: function(){},
? ? method2: function(){}
});
?
也等價于
define(function() {
return {
method1: function(){},
method2: function(){}
}
});
? 非獨立模塊,對其他模塊有依賴。
define([ 'module1', 'module2' ], function(m1, m2) {
? ? ...
});
?
或者:define(function(require) {
var m1 = require('module1'),
m2 = require('module2');
...
});
?
?
?
?
?
?
簡單看了一下RequireJS的實現方式,其 require 實現只不過是提取 require 之后的模塊名,將其放入依賴關系之中。
?
? require方法調用模塊
在require進行調用模塊時,其參數與define類似。
require(['foo', 'bar'], function(foo, bar) {
? ? foo.func();
? ? bar.func();
} );
在加載 foo 與 bar 兩個模塊之后執行回調函數實現具體過程。
官網 (http://www.requirejs.org/)
API (http://www.requirejs.org/docs/api.html)
4.CMD和SeaJS
?
CMD是SeaJS 在推廣過程中對模塊定義的規范化產出
? 對于依賴的模塊AMD是提前執行,CMD是延遲執行。不過RequireJS從2.0開始,也改成可以延遲執行(根據寫法不同,處理方式不通過)。
? CMD推崇依賴就近,AMD推崇依賴前置。
?
//AMD
define(['./a','./b'], function (a, b) {
?//依賴一開始就寫好
? ? a.test();
? ? b.test();
});
?
//CMD
define(function (requie, exports, module) {
? ? ?
? ? //依賴可以就近書寫
? ? var a = require('./a');
? ? a.test();
? ? ?
? ? ...
? ? //軟依賴
? ? if (status) {
? ? ?
? ? ? ? var b = requie('./b');
? ? ? ? b.test();
? ? }
});
?
雖然 AMD也支持CMD寫法,但依賴前置是官方文檔的默認模塊定義寫法。
? AMD的API默認是一個當多個用,CMD嚴格的區分推崇職責單一。例如:AMD里require分全局的和局部的。CMD里面沒有全局的 require,提供 seajs.use()來實現模塊系統的加載啟動。CMD里每個API都簡單純粹。
?
5.?UMD
UMD是AMD和CommonJS的糅合
AMD模塊以瀏覽器第一的原則發展,異步加載模塊。
CommonJS模塊以服務器第一原則發展,選擇同步加載,它的模塊無需包裝(unwrapped modules)。
這迫使人們又想出另一個更通用的模式UMD (Universal Module Definition)。希望解決跨平臺的解決方案。
UMD先判斷是否支持Node.js的模塊(exports)是否存在,存在則使用Node.js模塊模式。
在判斷是否支持AMD(define是否存在),存在則使用AMD方式加載模塊。
?
(function (window, factory) {
? ? if (typeof exports === 'object') {
? ? ?
? ? ? ? module.exports = factory();
? ? } else if (typeof define === 'function' && define.amd) {
? ? ?
? ? ? ? define(factory);
? ? } else {
? ? ?
? ? ? ? window.eventUtil = factory();
? ? }
})(this, function () {
//module …
});
?
(function (root, factory) {
? ? if (typeof define === 'function' && define.amd) {
? ? ? ? // AMD
? ? ? ? define(['jquery', 'underscore'], factory);
? ? } else if (typeof exports === 'object') {
? ? ? ? // Node, CommonJS之類的
? ? ? ? module.exports = factory(require('jquery'), require('underscore'));
? ? } else {
? ? ? ? // 瀏覽器全局變量(root 即 window)
? ? ? ? root.returnExports = factory(root.jQuery, root._);
? ? }
}(this, function ($, _) {
? ? //? ? 方法
? ? function a(){};? ? //? ? 私有方法,因為它沒被返回 (見下面)
? ? function b(){};? ? //? ? 公共方法,因為被返回了
? ? function c(){};? ? //? ? 公共方法,因為被返回了
?
? ? //? ? 暴露公共方法
? ? return {
? ? ? ? b: b,
? ? ? ? c: c
? ? }
}));
?
轉載于:https://www.cnblogs.com/Super-scarlett/p/8260458.html
總結
以上是生活随笔為你收集整理的CommonJS/AMD/CMD/UMD的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【图文详细教程】maven3安装配置+e
- 下一篇: 2017美国专利榜:IBM称霸全球!华为