皆为前端工程化中定义模块(module)的规则,如:模块标识,模块依赖,模块实现,模块对外接口,模块加载;
实现时有:异步,同步,依赖前置,依赖就近,预执行,懒执行,软依赖,硬依赖,模块对象支持类型等差异;
Javascript的灵活性、借鉴性、标准难产落地性,带来模块的实现方式(运行时加载/编译静态加载)有本质的差异,代码风格(require,return/import,export)有形式上的差异。
CommonJS Modules/1.0规范,概述, wiki
在服务器上或本地桌面应用程序,定义了模块格式,如node模块的实现,
仅支持对象类型的模块,同步加载。
如模块qux
:
// filename: qux.js
// dependencies
var $ = require('jquery');
// methods
function foo(){};
// exposed public method (single)
module.exports = foo;
// filename: qux.js
var $ = require('jquery');
var _ = require('underscore');
// methods
function foo(){}; // private because it's omitted from module.exports (see below)
function bar(){}; // public because it's defined in module.exports
function baz(){}; // public because it's defined in module.exports
// exposed public methods
module.exports = {
bar: bar,
baz: baz
};
Asynchronous Module Definition, 概述, Why AMD?
异/同步加载
支持对象、函数、构造器、字符串、JSON等各种类型的模块。
AMD 早期实现为 依赖前置,提前执行
define(id?, dependencies?, factory);
如模块qux
:
// filename: qux.js
define(['jquery'], function ($) {
// methods
function foo(){
};
// exposed public methods
return foo;
});
// filename: qux.js
define(['jquery', 'underscore'], function ($, _) {
// methods
function foo(){
}; // private because it's not returned (see below)
function bar(){
}; // public because it's returned
function baz(){
}; // public because it's returned
// exposed public methods
return {
bar: bar,
baz: baz
}
});
兼容CommonJS规范:
// filename: qux.js
define(function (require, exports, module) {
// dependencies
var $ = require('jquery');
_ = require('underscore');
// exposed public methods
exports.foo= function () {
}
});
Common Module Definition, 概述, 中文
define(function(require,exports,module){...});
CMD实现为 依赖就近,延迟执行
Universal Module Definition
识别当前环境所支持的模块风格,兼容不同的加载规范
// code from https://github.com/tangshuang/omd
(function(factory){
"use strict";
// change to your module name
var NAME = 'omd';
if(typeof define == 'function' && (define.cmd || define.amd)) { // amd & cmd
define(function(require){
var requires = {
/**
* dependences:
* 1. need to fill requires
* 2. use require, moudule name should be defined before
* 3. relative path is not allowed in cmd & amd mode
*/
// 'jquery' : require('jquery'),
// 'bootstrap' : require('bootstrap')
};
var _require_ = function(key) {
return requires[key];
}
return factory(_require_);
});
}
else if(typeof module !== 'undefined' && typeof exports === 'object') { // nodejs
module.exports = factory(require); // in node, require can be used everywhere generally
}
else { // none module
this[NAME] = factory(function(key){
return this[key];
}.bind(this));
}
}).call(this || (typeof window !== 'undefined' ? window : global),function(require){
"use strict";
// require('jquery');
/**
* use return object to export. i.e.
* return {
name : 'module name',
init : function(opotions) {},
destory : function() {}
};
*/
});
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery', 'underscore'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS-like
module.exports = factory(require('jquery'), require('underscore'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.jQuery, root._);
}
}(this, function ($, _) {
// methods
function foo(){
}; // private because it's not returned (see below)
function bar(){
}; // public because it's returned
function baz(){
}; // public because it's returned
// exposed public methods
return {
bar: bar,
baz: baz
}
}));
import, export
ES标准下的模块,具有静态结构特性,编译时 Tree Shaking 可去 dead-code ;
引用自及扩展阅读: