前端模块化

模块化是标准,不是实现

什么是前端模块化

  1. 复杂的程序根据规范拆成若干,一个模块中包含输入、输入
  2. 模块内部私有化,对外暴露接口与其它模块进行通信

脚本和模块的区别

  • 脚本 都在一个js文件中
  • 模块 有入口文件,引入不同的模块,代码上更易读

模块化进化过程

1. 全局function函数,不同功能封装不同函数

  • *缺陷:全局直接挂在到window上,容易引发全局命名冲突

2. 全局namepace模块,通过对象封装模块

window.__module = {
	var a = 1;
	handle() {}
}

缺陷: 外部能修改对象中的变量

3. IIFE模式,自执行函数创建闭包

(function() {
	var x = 1;
	function handle() {
	
	};
	function getX() {
		return x
	};
	function setX(v) {
		x = v
	}
	window.__module = {
		x,
		handle,
		setX,
		getX
	}
})()

缺陷: 模块无法互相通信

  • 函数作用域内变量和对象属性值的区别
const m = window.__module

console.log(m.x) // 1(相当于将函数作用域内的变量x,拷贝到对象中,生成一个新的属性x)
console.log(m.getX()) // 1
m.setX(2)
console.log(m.x) // 1
console.log(m.getX()) // 2

4. IIFE模式增强,支持传入自定义依赖

缺陷:

  • 多依赖传入,代码阅读困难
  • 无法支持大规模的模块化开发
  • 无特定语法支持,代码简陋
// test-api.js   
(function(global) {
    var x = 1

    function setX(v) {
        x = v
    }

    function getX() {
        return x
    }

    global.__module_API = {
        x,
        setX,
        getX
    }
})(window)

// test-sum.js
(function(global, api) {
    function sum(a, b) {
        return a+b
    }

    global.__module = {
        api,
        sum
    }
})(window, window.__module_API)

const m = window.__module

console.log('x', m.api.x);
console.log('getX', m.api.getX());
m.api.x = 2
m.api.setX(3)
console.log('x', m.api.x);
console.log('getX', m.api.getX());

<!-- test.html -->
<html>
    <header>
        <script src="./test-api.js"></script>
        <script src="./test-sum.js"></script>
    </header>
</html>

commonJS规范特点

  1. 所有代码都运行在模块作用域,不会污染全局作用域。
  2. 模块可以多次加载第一次加载时会运行模块,模块输出结果会被缓存,再加载时,会从缓存中直接读取模块。
  3. 模块的加载顺序,按照其在代码中出现的顺序进行加载
  4. 模块输出的值 是值的拷贝,类似IIFE方案中的内部变量。
// 导出
function test() {
	return 123
}
module.exports = {
 test
}

//导入
const {test} = require(./test.js)

⚠️ module.exports 会覆盖 exports 的导出

commonJS打包

browserify <文件path> -o <打包后path>

browserify打包原理

  1. 本质 通过自执行函数实现模块化。
  2. 将每个模块编号 存入一个对象 每个模块标记依赖模块。
  3. 实现了require方法,核心 通过call方法调用模块,传入require、module、exports方法,通过module存储模块信息,通过exports存储模块输出信息。

AMD规范

  1. 非同步加载模块,允许指定回调函数。
  2. node模块通常位于本地,加载速度快,适用于同步加载。
  3. 浏览器环境下,模块需要请求获取,所以适用于异步加载。
  4. require.js 是AMD的一个具体实现库

CMD规范

整合了commonJSAMD的优点

ESModule规范介绍

设计理念是希望在编译时就确定模块依赖关系及输入输出。
commonJS和AMD必须运行时才能确定依赖和输入、输出。
ESModule import加载模块 export输出模块

commonJS和ESModule规范对比

  1. commonJS模块输出是值的拷贝,ESModule模块输出是值的引用。
  2. commonJS模块是运行时加载,ESModule模块输出是值的引用。
  3. commonJS是单个值导出,而ESModule可以导出多个(import * as echarts from ‘echarts’ 类似这种导出多个)
  4. commonJS是同步加载,ESModule支持异步加载(import(模块).then(res => {})
  5. commonJS this指向当前模块(this === module.exports //true),ESModule this指向undefined

脚本和模块对比

  1. 模块具备更高开发效率(可读性强,复用高效)
  2. 脚本具有更高的页面性能(模块文件多,加载速度慢)
  3. ⚠️模块在浏览器中运行会存在兼容性问题

浏览器模块化的局限

  1. 缺乏模块管理,模块分散在各个项目中
  2. 性能加载慢,大型项目无法直接使用
  3. ⚠️npmwebpack解决以上两个问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值