模块
指的是将一个程序封装成多个模块,再组合起来用,这些模块只做自己负责的事情,并暴露一部分接口和数据进行通信。
传统模块化
function
功能:使用function方式作为封装各种不同的功能 弊端:污染全局命名空间,很容易造成命名冲突问题
namespace
减少了全局变量,解决了命名冲突问题 弊端:数据可能被外部直接修改,不安全
IIFE
私有数据,外部只能调用闭包暴露出来的方法和属性进行操作,如果出现模块需要依赖另外一个模块是怎么解决?
模块化优点
- 减少命名冲突
- 分离数据,按需加载
- 复用性和维护性更好
模块化规范
CJS
nodejs的模块化规范,每个文件可以是一个模块(需要声明导出),它们拥有自己的作用域。
js
// 暴露数据
module.exports = value
exports.xxx = value
// 引入模块
const myModule = require('./myModule.js')
如果导入时没有发现模块会报错
CJS导入是同步的,因为node模块一般都在本地硬盘,加载很快,无需异步导入 在服务器端模块可以按需加载,需要时才同步加载,而在浏览器中需要提前编译处理
优点
- 模块之间的作用域的独立的,不会污染全局
- 多次引入模块,只读取第一次,有缓存机制
- 根据引入顺序进行加载
AMD
异步加载模块+回调函数实现实现的,在浏览器中异步加载。
js
// 导出模块
define(function(){
return value
})
// 导出指定模块
define(['foo', 'bar'], function(m1, m2){
return value
})
// 引入模块
require(['foo', 'bar'], function(m1, m2){
// your code
})
CMD
专门用于浏览器,是异步加载的,可以理解为AMD
和CJS
的结合体
ESM
js
// 导出默认模块
export default value
// 导出指定数据
export const value
// 引入默认模块
import value from 'module'
// 引入指定数据
import {value} from 'module'
ESM和CJS区别
- CJS输出的是数值拷贝,ESM是值引用
- CJS运行时加载,ESM编译时输出接口
- ESM是静态定义,CJS是加载一个对象
module.exports={}