模块化机制

模块化

前端项目日益庞大,涉及到的业务方面越来越多,现在比较流行的是组件化开发,剩下就是模块化、工程化了。最新的ES6页支持了类class和模块module属性;对于模块化一直以来都不是特别清楚,趁机记录一下。

1.什么是JavaScript模块化

  • 什么是模块化?

    模块化,简单来说就是:在解决一个复杂问题或者一系列杂糅问题时,按照一种查分的思维吧问题进行系统性分解,分而划之进行处理。代码模块化,就是将复杂系统代码分解为结构更加合理、可维护性更高、便于管理的子模块的方式。对于软件行业来说,高内聚、低耦合的软件代码结构,使得不管系统的代码结构大小、业务的复杂性差异多大,系统都具有方便的管理性、开发敏捷性、高度可维护性。

  • 如何做到模块化设计

    模块化的设计的基本标准是分解、依赖、聚合,一个模块化系统必然具备以下几个特点:
    ①定义封装的模块;②定义新模块对其他模块的依赖;③对其他模块引入的支持;

2.实际场景中的模块化实现

弄清了模块化的原理,那么实际开发中我们如何运用这一设计模式,总要有一个或几个规范标准形式,这样才能统一大家的代码。JavaScript中出现了一些非传统开发方式的模块化规范:CommonJSAMDCMD.
看到眼花缭乱的AMD、CMD、UMD、sealJS、RequireJS、CommonJS经常让前端同学不知所措,开发过程中也是bug频频,这些都是什么意思,又有什么区别那,下面来进行一一说明。

2.1. CommonJS————同步加载、服务器端的模块化规范,采用案列:Node.js
  • 实现原理:
    • 一个单独的文件就是一个模块;
    • 加载模块采用同步方式,加载完成后才能执行后面的操作
    • 加载模块使用require方法,该方法读取一个文件并执行,最后返回内部的exports对象;
  • 特点:
    • 由于是同步加载。所以加载、执行完依赖文件后,才可执行后续的操作,即会产生同步阻塞;
    • 比较适合运用于服务器的编程,加载模块文件通常都存在本地磁盘,加载过程无延迟,无需异步加载;
      由于同步加载执行,存在同步阻塞问题,对于从远程服务器加载模块的浏览器环境不友好,
  • 栗子:
//lib.js
var privateVar=123;                     //局部变量
function funs(){                        //公有方法
  this.foo=fucntion(){//do something};  
  this.bar=function(){//do other things };
}
exports.funs=new funs();              // exports输出对象上的方法是公有方法
//require方法默认读取js文件,通常省略.js后缀
var funs=require(''./lib').funs;
funs.foo();
2.2 AMD————异步加载,采用案例:require.js
  • 实现原理: ‘Ansychronous Module Definition’–异步模块定义
    • 通过一个函数封装所有所需要、所依赖的模块/方法/对象/属性;返回一个新函数(模块);
    • 推崇依赖前置,依赖的模块提前执行;(require2.0开始支持延迟执行)
    • 采用依赖注入方式加载模块;
    • 注入依赖模块后,执行异步回调函数;
  • 特点:
    • 异步加载,不会产生异步阻塞,适合浏览器网络环境;
    • 同时允许异步加载、按需加载模块
  • 栗子:
    • 定义模块:define(id?,dependencies?,factory)
      ①id:模块标识,可选参数,字符串类型;②dependencies:当前模块的依赖模块标识,可选参数,数组类型;③factory:一个需要进行实例化的函数或者一个对象;
// 1. 定义无需依赖的模块
define({
  name:'jack';
  say:function(sex){ return `I am a ${sex}` }
})
// 2.定义有依赖的模块
define(['depModule'],fucntion(dep){
 return {
    varb:fucntion(){
      return dep.verb()+1;
    }
  }
})
// 3.定义具名模块
define('allDep',['depModuleA','depModuleB'],fucntion(depA,depB){
  export.varb=function(){
    return depA.fn();
  }
})
  • 加载模块:require([module],callback)
    ①[module]:需要加载的模块,数组类型;②callback:回调函数

    //
    require(['math'],fucntion(){
    math.add(arguments);
    })
2.3 CMD————异步加载、异步执行依赖,案例:SealJS

CMD 与 AMD 类似;都是采用异步加载,不同点主要有一下几点:
- 对依赖模块的执行时机:CMD延迟执行,AMD提前执行(RequireJS2.0后支持延迟执行)
- 依赖位置:CMD推崇依赖就近,按需加载;AMD推崇依赖前置;
- API:CMD推崇职责单一,AMD里面require分局部和全局方式;

2.4 UMD———异步加载,异步执行,兼容服务器、浏览器端,是AMD和CommonJS的糅合

AMD 以浏览器第一的原则,异步加载模块,加载的模块需经过包装;
CommonJS模块以服务器第一的原则,同步加载模块,加载的模块无需包装;
UMD :(Universal Module Definition)跨浏览器、服务器平台解决方案

  • 原理:
    • 首先判断是否支持Node.js模块(exports是否存在),存在则使用同步加载方案;
    • 再判断是否支持AMD(define是否存在),存在则是用异步加载方案
(function(){
  if( typeof exports==='object'){
    module.exports=factory();
  }else if (typeof define==='function' && define.amd){
      define(factory);
  }else{
    windoe.eventUtil=factory();
  }
})(this,function(){
// module ...  
})

你可能感兴趣的:(架构设计)