各类模块化简介及演变过程

 
第一阶段 : 无模块化

 
说明:
简单的将全部的js文件通通放在一块儿。可是这些文件的顺序还不能出错,好比jquery须要先引入,才能引入jquery插件,才能在其余的文件中使用jquery。
 
使用方法:
 
缺点:
  • 污染全局做用域。 由于每个模块都是暴露在全局的,简单的使用,会致使全局变量命名冲突,固然,咱们也能够使用命名空间的方式来解决。
  • 对于大型项目,各类js不少,开发人员必须手动解决模块和代码库的依赖关系,后期维护成本较高。
  • 依赖关系不明显,不利于维护。 好比main.js须要使用jquery,可是,从上面的文件中,咱们是看不出来的,若是jquery忘记了,那么就会报错。
 
 
第二阶段: CommonJS规范

 
说明:
CommonJS就是一个JavaScript模块化的规范。
  • 每个文件就是一个模块,其内部定义的变量是属于这个模块的,不会对外暴露,也就是说不会污染全局变量。
  • 核心思想:
  1. 经过 require 方法来同步加载所要依赖的其余模块,
  2. 经过 module.exports 来导出须要暴露的接口
 
使用方法:
 
优势:
在服务器端率先完成了JavaScript的模块化,解决了依赖、全局变量污染的问题,这也是js运行在服务器端的必要条件
 
缺点:
  • CommonJS 是同步加载模块的,只有加载完成,才能执行后面的操做
  • 因为 CommonJS 是同步加载模块的,在服务器端,文件都是保存在硬盘上,因此同步加载没有问题,可是对于浏览器端,须要将文件从服务器端请求过来,那么同步加载就不适用了,因此,CommonJS是不适用于浏览器端的。
 
 
第三阶段: AMD规范

说明:
  • 非同步加载模块,容许指定回调函数。所以浏览器端通常采用AMD规范。
  • AMD规范的实现:require.js
  1. 定义模块:define(id, [depends], callback)
第一个参数 id 为字符串类型,表示了模块标识,为可选参数。若不存在则模块标识应该默认定义为在加载器中被请求脚本的标识。若是存在,那么模块标识必须为顶层的或者一个绝对的标识。
第二个参数,dependencies ,是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。
第三个参数,factory,是一个须要进行实例化的函数或者一个对象。
  1. 加载模块:require([module], callback) 支持CommonJS的模块导出方式
 
使用方法:
 
优势:
  • 适合在浏览器环境中异步加载模块。
  • 能够并行加载多个模块。
 
缺点:
  • 提升了开发成本
  • 不能按需加载,而是必须提早加载全部的依赖
 
 
第四阶段: CMD规范

说明:
和requirejs很是相似,即一个js文件就是一个模块,可是CMD的加载方式更加优秀,是经过按需加载的方式。\
 
使用方法:
 
优势:
  • 实现了浏览器端的模块化加载。
  • 能够按需加载,依赖就近。
 
缺点:
  依赖SPM打包,模块的加载逻辑偏重。 
 
 
特殊存在: UMD规范

背景:
Modules/Wrappings是出于对NodeJS模块格式的偏好而包装下使其在浏览器中得以实现, 并且它的格式经过某些工具(如 r.js)也能运行在NodeJS中。事实上,这两种格式同时有效且都被普遍使用。
AMD以浏览器为第一(browser-first)的原则发展,选择异步加载模块。它的模块支持对象(objects)、函数(functions)、构造器(constructors)、字符串(strings)、JSON等各类类型的模块。所以在浏览器中它很是灵活。
CommonJS以服务器端为第一(server-first)的原则发展,选择同步加载模块。它的模块是无需包装的(unwrapped modules)且贴近于ES.next/Harmony的模块格式。但它仅支持对象类型(objects)模块。 
这迫使一些人又想出另外一个更通用格式  UMD(Universal Module Definition)。但愿提供一个先后端跨平台的解决方案。
 
说明:
UMD的实现很简单,先判断是否支持NodeJS模块格式(exports是否存在),存在则使用NodeJS模块格式。
再判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。前两个都不存在,则将模块公开的全局(window或global)。
 
第五阶段:ES6模块化(推荐使用)

说明:
  • ES6的模块化方案是真正的规范
  • 使用:
  1. 引入模块:使用 import
  2. 导出模块:经过 exprot
  • 目前没法在浏览器中执行,需经过babel将不被支持的import编译为当前受到普遍支持的 require
 
使用方法:
 
优势:
和requir区别不大,可是推荐使用ES6,毕竟官方
 
缺点:
  ES6目前没法在浏览器中执行,因此,咱们只能经过babel将不被支持的import编译为当前受到普遍支持的 require 
 
 
 
 
无模块化
CommonJS规范
AMD规范
CMD规范
ES6模块化
适用
 
服务端
浏览器端
浏览器端
浏览器端
加载方式
 
同步加载
异步加载、
模块开始加载全部依赖
按需加载
 
实现库
   
requireJs
seajs
 
来源
 
前端社区
前端社区
前端社区
官方
是否须要bebal编译
 
 
AMD和CMD的区别

  1. AMD 对于依赖的模块提早执行, CMD延迟执行
  2. AMD 推崇依赖前置, CMD推崇依赖就近,即只在须要用到某个模块的时候再require
参考资料:
相关文章
相关标签/搜索