JS 模块化

1、CommonJS
产生背景:一开始大家都认为JS是辣鸡,没什么用,官方定义的API只能构建基于浏览器的应用程序,CommonJS就按耐不住                       了,CommonJS API定义很多普通应用程序(主要指非浏览器的应用)使用的API,从而填补了这个空白。它的终极                     目标是提供一个类似Python,Ruby和Java标准库。这样的话,开发者可以使用CommonJS API编写应用程序,然后                     这些应用可以运行在不同的JavaScript解释器和不同的主机环境中。2009年,美国程序员Ryan Dahl创造了node.js项                     目,将javascript语言用于服务器端编程。这标志"Javascript模块化编程"正式诞生。因为老实说,在浏览器环境下,没                   有模块也不是特别大的问题,毕竟网页程序的复杂性有限;但是在服务器端,一定要有模块,与操作系统和其他应用                   程序互动,否则根本没法编程。
具体代表:nodeJs、webpack    
原理:浏览器不兼容CommonJS的根本原因,在于缺少四个Node.js环境的变量(module,exports,require,global,只要能够提供这            四个变量,浏览器就能加载 CommonJS 模块。
简单实现
var module = {
  exports: {}
};

(function(module, exports) {
  exports.multiply = function (n) { return n * 1000 };
}(module, module.exports))

var f = module.exports.multiply;
f(5) // 5000 
      
上面代码向一个立即执行函数提供 module 和 exports 两个外部变量,模块就放在这个立即执行函数里面。模块的输出值放在 module.exports 之中,这样就实现了模块的加载。

2、AMD
产生背景:基于commonJS规范的nodeJS出来以后,服务端的模块概念已经形成,但是,由于一个重大的局限,使得CommonJS                    规范不适用于浏览器环境。var math = require('math'); math.add(2, 3);require 是同步的.这对服务器端不是一个问                          题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这                    却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状                    态。浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD                      规范诞生的背景。
具体代表:RequireJS
用法示例:require([dependencies], function(){}); 
require()函数接受两个参数
第一个参数是一个数组,表示所依赖的模块
第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块
// 定义模块 myModule.js
define(['dependency'], function(){
    var name = 'Byron';
    function printName(){
        console.log(name);
    }

    return {
        printName: printName
    };
});

// 加载模块
require(['myModule'], function (my){
  my.printName();
});


3、CMD
产生背景:CMD 即Common Module Definition通用模块定义,CMD规范是国内发展出来的,就像AMD有个requireJS,CMD有个浏览器的实现SeaJS,SeaJS要解决的问题和requireJS一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同 
具体代表:Sea.js
用法示例:factory是一个函数,有三个参数,function(require, exports, module)
require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口:require(id)
exports 是一个对象,用来向外提供模块接口
module 是一个对象,上面存储了与当前模块相关联的一些属性和方法
// 定义模块  myModule.js
define(function(require, exports, module) {
  var $ = require('jquery.js')
  $('div').addClass('active');
});

// 加载模块
seajs.use(['myModule.js'], function(my){

});


AMD与CMD区别:
执行机制:SeaJS对模块的态度是懒执行, 而RequireJS对模块的态度是预执行
遵循规范:RequireJS 遵循 AMD(异步模块定义)规范,Sea.js 遵循 CMD (通用模块定义)规范。规范的不同,导致了两者 API 不同

4、ES6 Modules
产生背景:Es6*之前*JavaScript一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来,这对开发大型的、复杂的项目形成了巨大障碍。为了解决模块依赖加载问题,出现了AMD,CMD,COMMONJS ,其中AMD,CMD(两者之间也存在差异,后期会说)用于客户端,COMMONJS用于服务端,es6出现后,定义了Module功能,而且实现得相当简单,完全可以取代现有的CommonJS和AMD规范,成为浏览器和服务器通用的模块解决方案。
用法示例: export(抛出) import(引入)  export default(其他模块加载该模块时,import命令可以为该匿名函数指定任意名字)

猜你喜欢

转载自blog.csdn.net/davidPan1234/article/details/81563224