您的位置:首页 > Web前端 > JavaScript

使用AMD,CommonJS和ES Harmony编写模块化JavaScript代码(AMD VS CJS)

2016-12-06 14:36 495 查看

AMD vs. CommonJS 竞争,但同样有效的标准

本文强调使用AMD要多于CommonJS,但是实际上它们各有用武之地。

AMD更适合浏览器优先开发,适用于一步行为,以及简化向后兼容,但是它并不包含文件I/O的概念。它支持对象,函数,构造器,字符串,JSON以及很多类型的模块,可以直接在浏览器中运行,具有较高的灵活性。

CommonJS这是适于作为服务优先的解决方案,更是和同步行为,项John Hann所推荐的,不存在全局的baggage,并且对未来的服务端开发有更强的适应性。这样说是因为,CJS支持非封装的模块,感觉更像是ES.next/Harmony的规范,对AMD中强制要求的
define()
在这里不再被强制要求。但是CJS模块仅支持对象作为模块。

虽然不同模块的不同规范可能令人混淆,但是你可能会对混合AMD/CJS和通用AMD/CJS模块感兴趣。

基础AMD混合规范(John Hann)

define( function (require, exports, module){

var shuffler = require('lib/shuffle');

exports.randomize = function( input ){
return shuffler.shuffle(input);
}
});


AMD/CommonJS通用模块定义(Variation 2, UMDjs)

/**
* exports object based version, if you need to make a
* circular dependency or need compatibility with
* commonjs-like environments that are not Node.
*/
(function (define) {
//The 'id' is optional, but recommended if this is
//a popular web library that is used mostly in
//non-AMD/Node environments. However, if want
//to make an anonymous module, remove the 'id'
//below, and remove the id use in the define shim.
define('id', function (require, exports) {
//If have dependencies, get them here
var a = require('a');

//Attach properties to exports.
exports.name = value;
});
}(typeof define === 'function' && define.amd ? define : function (id, factory) {
if (typeof exports !== 'undefined') {
//commonjs
factory(require, exports);
} else {
//Create a global function. Only works if
//the code does not have dependencies, or
//dependencies fit the call pattern below.
factory(function(value) {
return window[value];
}, (window[id] = {}));
}
}));


扩展的UMD插件(我和Thomas Davis)

core.js

// Module/Plugin core
// Note: the wrapper code you see around the module is what enables
// us to support multiple module formats and specifications by
// mapping the arguments defined to what a specific format expects
// to be present. Our actual module functionality is defined lower
// down, where a named module and exports are demonstrated.

;(function ( name, definition ){
var theModule = definition(),
// this is considered "safe":
hasDefine = typeof define === 'function' && define.amd,
// hasDefine = typeof define === 'function',
hasExports = typeof module !== 'undefined' && module.exports;

if ( hasDefine ){ // AMD Module
define(theModule);
} else if ( hasExports ) { // Node.js Module
module.exports = theModule;
} else { // Assign to common namespaces or simply the global object (window)
(this.jQuery || this.ender || this.$ || this)[name] = theModule;
}
})( 'core', function () {
var module = this;
module.plugins = [];
module.highlightColor = "yellow";
module.errorColor = "red";

// define the core module here and return the public API

// this is the highlight method used by the core highlightAll()
// method and all of the plugins highlighting elements different
// colors
module.highlight = function(el,strColor){
// this module uses jQuery, however plain old JavaScript
// or say, Dojo could be just as easily used.
if(this.jQuery){
jQuery(el).css('background', strColor);
}
}
return {
highlightAll:function(){
module
cf77
.highlight('div', module.highlightColor);
}
};

});


myExtension.js

;(function ( name, definition ) {
var theModule = definition(),
hasDefine = typeof define === 'function',
hasExports = typeof module !== 'undefined' && module.exports;

if ( hasDefine ) { // AMD Module
define(theModule);
} else if ( hasExports ) { // Node.js Module
module.exports = theModule;
} else { // Assign to common namespaces or simply the global object (window)

// account for for flat-file/global module extensions
var obj = null;
var namespaces = name.split(".");
var scope = (this.jQuery || this.ender || this.$ || this);
for (var i = 0; i < namespaces.length; i++) {
var packageName = namespaces[i];
if (obj && i == namespaces.length - 1) {
obj[packageName] = theModule;
} else if (typeof scope[packageName] === "undefined") {
scope[packageName] = {};
}
obj = scope[packageName];
}

}
})('core.plugin', function () {

// define your module here and return the public API
// this code could be easily adapted with the core to
// allow for methods that overwrite/extend core functionality
// to expand the highlight method to do more if you wished.
return {
setGreen: function ( el ) {
highlight(el, 'green');
},
setRed: function ( el ) {
highlight(el, errorColor);
}
};

});


app.js

$(function(){

// the plugin 'core' is exposed under a core namespace in
// this example which we first cache
var core = $.core;

// use then use some of the built-in core functionality to
// highlight all divs in the page yellow
core.highlightAll();

// access the plugins (extensions) loaded into the 'plugin'
// namespace of our core module:

// Set the first div in the page to have a green background.
core.plugin.setGreen("div:first");
// Here we're making use of the core's 'highlight' method
// under the hood from a plugin loaded in after it

// Set the last div to the 'errorColor' property defined in
// our core module/plugin. If you review the code further down
// you'll see how easy it is to consume properties and methods
// between the core and other plugins
core.plugin.setRed('div:last');
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript 模块化 amd