让你的插件兼容AMD, CMD ,CommonJS和 原生 JS

3,646 阅读2分钟

模块标准

// 支持AMD,CMD以及原生js的引用
  if (typeof module !== 'undefined' && typeof exports === 'object' && define.cmd) {
    module.exports = SB;
  } else if (typeof define === 'function' && define.amd) {
    define(function() {
      return SB;
    });
  } else {
    this.SB= SB;
  }
}).call(function() {
  return this || (typeof window !== 'undefined' ? window : global);
}
 //做的工作其实就是这么粗暴,判断当前用的什么就以当前规范来定义
    (function (root, factory) {
        if (typeof define === 'function' && define.amd) {
            // AMD
            define(['jquery'], factory);
        } else if (typeof exports === 'object') {
            // CommonJS
            module.exports = factory(require('jquery'));
        } else {
            //  全局变量
            root.returnExports = factory(root.jQuery);
        }
    }(this, function ($) {
        //    methods
        function myFunc(){};
        //    exposed public method
        return myFunc;
    }));

UMD:
Universal Module Definition 通用模块规范。
基于统一规范的目的出现,看起来没那么简约,但是支持amd和commonjs以及全局模块模式。

//做的工作其实就是这么粗暴,判断当前用的什么就以当前规范来定义
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
module.exports = factory(require('jquery'));
} else {
// 全局变量
root.returnExports = factory(root.jQuery);
}
}(this, function ($) {
// methods
function myFunc(){};
// exposed public method
return myFunc;
}));


现在的前端模块化标准主要有两种, CMD , AMD

CMD

CMD 在模块定义当中有三个变量,分别是 require , exports , module 。除了这三个变量可以辨识 CMD 外, define 函数还有一个公有属性 define.cmd 。我们也可以检测这个值来判断是否是 CMD

如果想要对外提供接口的话,可以将接口绑定到 exports (即 module.exports ) 上。

function MyModule() {
    // ...
}

if(typeof module !== `undefined` && typeof exports === `object` && define.cmd) {
    module.exports = MyModule;
}

如果需要支持除了 CMD 之外的其他符合 CommonJS 的标准,请去掉 define.cmd

AMD

AMD 规范中, define 函数同样有一个公有属性 define.amd

AMD 中的参数便是这个模块的依赖。那么如何在 AMD 中提供接口呢?它是返回一个对象,这个对象就作为这个模块的接口,故我们可以这样写:

function MyModule() {
    // ...
}

if(typeof define === `function` && define.amd) {
    define(function() { return MyModule; });
}

总结

我们除了提供 AMD 模块接口, CMD 模块接口,还得提供原生的 JS 接口,一个直接可以用的代码如下:

;(function(){
	function MyModule() {
		// ...
	}
	var moduleName = MyModule;
	if (typeof module !== 'undefined' && typeof exports === 'object' && define.cmd) {
		module.exports = moduleName;
	} else if (typeof define === 'function' && define.amd) {
		define(function() { return moduleName; });
	} else {
		this.moduleName = moduleName;
	}
}).call(function() {
	return this || (typeof window !== 'undefined' ? window : global);
});

一般插件的做法:

	if (typeof module != 'undefined' && module.exports) {  //CMD
		module.exports = SB;
	} else if (typeof define == 'function' && define.amd) {  //AMD
		define(function() {
			return SB;
		});
	} else {           //no AMD or CMD
		window.SB= SB;
	}