UMD、CommonJS、ES Module、AMD、CMD模块的写法
AMD异步模块规范
RequireJS就是AMD的一个典型的实现。
以下是一个只依赖与jQuery的模块代码:
// foo.js define(['jquery'], function($){ //此为工厂函数 function myFunc(){}; // 暴露公共方法 return myFunc; })
define(['jquery', 'underscore'], function($, _){ function a(){}; // 私有方法,没有被返回 function b(){}; function c(){}; // 暴露公共方法 return { b: b, c: c } })
CMD (Common Module Definition)
define(function(require, exports, module) { var a = require('./a') var b = require('./b') // 依赖可以就近书写 // 通过 exports 对外提供接口 exports.doSomething = function(){} // 或者通过 module.exports 提供整个接口 module.exports = {} })
<script src="sea.js"></script> <script> seajs.use('dialog', function(Dialog) { Dialog.init(/* 传入配置 */); }); </script>
Sea.js 还提供了 nocache、debug 等插件,拥有在线调试等功能,能比较明显地提升效率。
Sea.js 还提供了 combo、flush 等插件,配合服务端,可以很好地对页面性能进行调优。
CMD 模块定义规范与 Node.js 的模块规范非常相近。通过 Sea.js 的 Node.js 版本,可以很方便实现模块的跨服务器和浏览器共享。
CommonJS
与node.js的格式非常相似。可配合Browserify进行使用。
Browserify 可以让你使用类似于 node 的 require() 的方式来组织浏览器端的 Javascript 代码,通过预编译让前端 Javascript 可以直接使用 Node NPM 安装的一些库。
// foo.js var $ = require('jquery'); function myFunc(){}; module.exports = myFunc;
var $ = require('jquery'); var _ = require('underscore'); function a(){}; // 私有 function b(){}; function c(){}; module.exports = { b: b, c: c }
UMD通用模块规范
由于CommonJS和AMD都十分流行,但似乎缺少一个统一的规范。于是,UMD(通用模块规范)出现了,它可以同时支持这两种风格。
虽然这个模式的写法比较难看,但是,它同时兼容了AMD和CommonJS,而且还支持老式的全局变量规范。
UMD:Universal Module Definition(通用模块规范)是由社区想出来的一种整合了CommonJS和AMD两个模块定义规范的方法。
基本原理
用一个工厂函数来统一不同的模块定义规范。
原则
- 所有定义模块的方法需要单独传入依赖
- 所有定义模块的方法都需要返回一个对象,供其他模块使用
(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定义一个toggler模块:
(function (global, factory) { if (typeof exports === 'object' && typeof module !== undefined) { //检查CommonJS是否可用 module.exports = factory(require('jquery')); } else if (typeof define === 'function' && define.amd) { //检查AMD是否可用 define('toggler', ['jquery', factory]) } else { //两种都不能用,把模块添加到JavaScript的全局命名空间中。 global.toggler = factory(global, factory); } })(this, function ($) { function init() { } return { init: init } });
ES Module
// profile.js var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export {firstName, lastName, year};
//import obj from ‘xxx 只会导出这个默认的对象作为一个对象obj,
// main.js import {firstName, lastName, year} from './profile'; function setName(element) { element.textContent = firstName + ' ' + lastName; }
再例如整体加载模块
// circle.js export function area(radius) { return Math.PI * radius * radius; } export function circumference(radius) { return 2 * Math.PI * radius; }
//注释:import * as obj from ‘xxx’会将 若干export导出的内容组合成一个对象obj返回;
import * as circle from './circle'; console.log('圆面积:' + circle.area(4)); console.log('圆周长:' + circle.circumference(14));
// export-default.js export default function () { console.log('foo'); }
(支持amd、cmd、commonjs规范的模块加载) 即UMD
;(function( global, factory ){ "use strict"; if ( typeof module === "object" && typeof module.exports === "object" ) { // For CommonJS and CommonJS-like environments where a proper `window` // is present, execute the factory and get jQuery. // For environments that do not have a `window` with a `document` // (such as Node.js), expose a factory as module.exports. // This accentuates the need for the creation of a real `window`. // See ticket #14549 for more info. module.exports = global.document ? factory( global, true ) : function( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); }; } else if (define && define.cmd) { define( function () { return factory(global); } ); } else { factory( global ); } })( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { // 核心逻辑代码... // 使代码支持 amd 模块加载 if ( typeof define === "function" && define.amd ) { define( "jquery", [], function() { return jQuery; } ); } return { add: function(a, b) { return a + b } } }) --------------------- 参考:https://blog.csdn.net/Jacoh/article/details/85720146