首页 > 其他 > 详细

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

时间:2018-03-02 18:20:35      阅读:191      评论:0      收藏:0      [点我收藏+]
 
第一阶段 : 无模块化

 
说明:
简单的将所有的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
参考资料:

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

原文:https://www.cnblogs.com/ailsa-qin/p/8494219.html

踩
(0)
赞
(0)
   
举报
评论 一句话评论(0)
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!