前端模块化开发

一、模块化概述

1、概念

模块化:对于一个复杂的程序,将其按照一定的规范封装成几个文件块,每一块向外暴露一些接口, 但是块的内部数据是私有的, 块与块之间通过暴露的接口进行通信,这个过程称为模块化。

一个模块就是一个实现特定功能的文件,模块化通过把我们的复杂代码按照功能的不同,划分为不同的模块单独维护的方式。现在模块化是一种最主流的代码组织方式。

2、特点

  • 代码封装,避免全局污染
  • 具有唯一标识
  • 暴露部分数据或者api方法供外部使用
  • 模块使用方便快捷

3、模块化演变过程


(1)文件划分方式

将每个功能和相关的一些状态数据单独存放在不同的文件当中,此时一个文件就是一个独立的模块。然后将这个模块引入页面当中,直接调用模块中的成员(变量/函数),一个script标签就对应一个模块,所有模块都在全局范围内工作。


缺点

  • 污染全局作用域
  • 命名冲突问题
  • 无法管理模块依赖关系

(2)对象封装

将所有模块成员封装在一个对象中,当要使用的时候就调用这个对象的属性

const suit = {
  id: 'suit_1',
  type: 'input',
  value: '123',
  getType() {
    console.log(`type-${this.type}`);
    return this.type;
  }
  getValue() {
    console.log(`value-${this.value}`);
    return this.value;
  },

}
suit.type = 'checkbox' // 直接修改模块内部的数据
suit.getType() // 'checkbox'


缺点:

  • 没有私有空间,模块成员仍然可以在外部被访问或修改
  • 无法管理模块依赖关系

(3)立即执行函数

采用该方式为模块提供私有空间,将模块中每个成员都放在一个函数提供对的私有作用域中,可确保私有成员的安全。私有成员只能在模块成员内通过闭包的形式访问。

(function(){
     var name='A';
     
     function fn1(){
         console.log(name+'-fn1');
     }
     window.A={
         fn1
     }
})()
(function(){
     var name='B';
     
     function fn1(){
         console.log(name+'-fn1');
     }
     window.B={
         fn1
     }
})()

//
<script>
    A.fn1();//A-fn1
    B.fn1();//B-fn1
</script>

 二、模块化规范

前端模块化规范有三种:CommonJs、AMD、CMD;

  1. CommonJs用在服务器端,AMD和CMD用在浏览器环境
  2. AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。提前执行(异步加载:依赖先执行)+延迟执行
  3. CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。延迟执行(运行到需加载,根据顺序执行)延迟执行(运行到需加载,根据顺序执行)

CommonJS

(1)CommonJS概述

  • node应用由模块组成,采用common.js模块规范。每一个文件就是一个模块,拥有自己独立的作用域、变量、方法等,读其他的模块不可见
  • CommonJS规范规定,module变量代表当前模块,其是一个对象,其属性exports,即module.exports,是对外的接口
  • require方法用于加载模块,可以帮我们导入其他模块中的内容

(2)CommonJS特点

  • 所有代码都运行在模块作用域,不会污染全局作用域。
  • 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
  • 模块加载的顺序,按照其在代码中出现的顺序。
  • 运行时同步加载

(3) commonjs实现原理 

每个模块文件上有三个变量:

  • module 记录当前模块信息
  • require 引入模块方法
  • exports 当前模块导出的属性

可以再commonjs规范下每一个js模块上直接使用他们

 

(function(exports,require,module,__filename,__dirname){
   const setName = require('data.js')
    module.exports = function set(){
        return {
            name: setName(),
            title: 'CommonJs方法'
        }
    }
})

(4)CommonJS模块的加载机制

一个模块除了自己的函数作用域之外,最外层还有一个模块作用域,module代表这个模块,是一个对象,exports是module的属性,是对外暴露的接口。

require也在这个模块的上下文中,用来引入外部模块,其实就是加载其他模块的module.exports属性。
 

AMD规范

异步模块定义

(1)概述

由于不是JavaScript原生支持,使用AMD规范进行页面开发需要用到对应的库函数,也就是RequireJS,实际上AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出。

它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

规范

define(id?, dependencies?, factory);

用全局函数define来定义模块
1、id

id为模块标识,遵从CommonJS Module Identifiers规范;
2、dependencies

dependencies为依赖的模块数组,在factory中需传入形参与之一一对应
如果dependencies的值中有"require"、“exports"或"module”,则与commonjs中的实现保持一致
如果dependencies省略不写,则默认为[“require”, “exports”, “module”],factory中也会默认传入require,exports,module;
3、factory

如果factory为函数,模块对外暴漏API的方法有三种:return任意类型的数据、exports.xxx=xxx、module.exports=xxx
如果factory为对象,则该对象即为模块的返回值


具体分析AMD我们通过require.js来进行。require.js是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一;
RequireJS主要解决两个问题

  • 多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
  • js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长

RequireJs也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:

第一个参数[module],是一个数组,里面的成员就是要加载的模块

第二个参数callback,则是加载成功之后的回调函数。math.add()与math模块加载不是同步的,浏览器不会发生假死。

 CMD规范

CMD的全称是Common Module Definition,即通用模块定义。

实现的JavaScript库为sea.js。它和AMD的require.js很像,但加载方式不同,它是按需就近加载的,而不是在模块的开始全部加载完成。它有以下两大核心特点:

简单友好的模块定义规范:Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码。
自然直观的代码组织方式:依赖的自动加载、配置的简洁清晰,可以让我们更多地享受编码的乐趣。

在CMD规范中,一个文件就是一个模块,代码书写的格式是这样的:

define(factory);

当factory为函数时,表示模块的构造方法,执行该方法,可以得到该模块对外提供的factory接口,factory 方法在执行时,默认会传入三个参数:require、exports 和 module: 

// 所有模块都通过 define 来定义
define(function(require, exports, module) {

  // 通过 require 引入依赖
  var a = require('./spinning');

  // 通过 exports 对外提供接口
  exports.doSomething = ...

  // 或者通过 module.exports 提供整个接口
  module.exports = ...

});

require.js的做法是并行加载所有依赖的模块, 等完成解析后, 再开始执行其他代码, 因此执行结果只会"停顿"1次, 而Sea.js在完成整个过程时则是每次需要相应模块都需要进行加载,这期间会停顿是多次的,因此require.js从整体而言相对会比Sea.js要快一些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值