前端模块化
将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起
块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信
模块化的进化过程
全局function模式 : 将不同的功能封装成不同的全局函数
编码: 将不同的功能封装成不同的全局函数。
问题: 污染全局命名空间, 容易引起命名冲突或数据不安全,而且模块成员之间看不出直接关系。

namespace模式 : 简单对象封装
作用: 减少了全局变量,解决命名冲突。
问题: 数据不安全(外部可以直接修改模块内部的数据)。

这样的写法会暴露所有模块成员,内部状态可以被外部改写。
IIFE模式:匿名函数自调用(闭包)
作用: 数据是私有的, 外部只能通过暴露的方法操作
编码: 将数据和行为封装到一个函数内部, 通过给window添加属性来向外暴露接口
问题: 如果当前这个模块依赖另一个模块怎么办?


IIFE模式优化 : 引入依赖
这就是现代模块实现的基石。

html文件

上例子把jQuery库当作参数传入。这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显。
模块化的好处
避免命名冲突(减少命名空间污染)
更好的分离, 按需加载
更高复用性
高可维护性
引入多个<script>后出现出现问题
请求过多:首先我们要依赖多个模块,那样就会发送多个请求,导致请求过多
依赖模糊:我们不知道他们的具体依赖关系是什么,也就是说很容易因为不了解他们之间的依赖关系导致加载先后顺序出错。
难以维护:以上三种原因就导致了很难维护,很可能出现牵一发而动全身的情况导致项目出现严重的问题。
模块化固然有多个好处,然而一个页面需要引入多个js文件,就会出现以上这些问题。而这些问题可以通过模块化规范来解决。
模块化规范



我们用一个例子,来讲清楚这两个规范之间最大的差异:依赖前置和就近依赖。


./world的执行显示为浅色
结论:CMD的输出结果中,没有打印"world init"。但是,需要注意的是,CMD没有打印"world init"并是不world.js文件没有加载。AMD与CMD都是在页面初始化时加载完成所有模块,唯一的区别就是就近依赖是当模块被require时才会触发执行。