JS模块化
模块化的理解
模块化主要解决两个问题:命名冲突和文件依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 生态 诞生时间 CommonJS 2009年 Node.js 2009年 NPM 2010年 requireJS(AMD) 2010年 异步模块定义 async module definition seaJS(CMD) 2011年 common module define broswerify 2011年 webpack 2012年 grunt 2012年 gulp 2013年 react 2013年 vue 2014年 ES6(Module) 2015年 angular 2016年 redux 2015年 vite 2020年 snowpack 2020年 跨端 rollup truopack
|
模块化的进程
全局function模式
将不同的功能封装成不同的全局函数
问题:污染全局命名空间,容易引起命名冲突
1 2 3 4 5 6
| function m1(){ } function m2(){ }
|
namespace模式
简单对象封装
作用:减少了全局变量,解决命名冲突
问题:数据不安全(外部可以直接修改模块内部的数据)
1 2 3 4 5 6 7 8 9 10 11
| let myModule = { data: 'www.baidu.com', foo() { console.log(`foo() ${this.data}`) }, bar() { console.log(`bar() ${this.data}`) } } myModule.data = 'other data' myModule.foo()
|
IIFE模式
immediately-invoked function expression 匿名函数自调用(闭包)
作用:数据是私有的, 外部只能通过暴露的方法操作。将数据和行为封装到一个函数内部, 通过给window添加属性来向外暴露接口
问题:如果当前这个模块依赖另一个模块怎么办?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <script type="text/javascript" src="module.js"></script> <script type="text/javascript"> myModule.foo() myModule.bar() console.log(myModule.data) myModule.data = 'xxxx' myModule.foo() </script>
(function(window) { let data = 'www.baidu.com' function foo() { console.log(`foo() ${data}`) } function bar() { console.log(`bar() ${data}`) otherFun() } function otherFun() { console.log('otherFun()') } window.myModule = { foo, bar } })(window)
|
IIFE模式增强
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| (function(window, $) { let data = 'www.baidu.com' function foo() { console.log(`foo() ${data}`) $('body').css('background', 'red') } function bar() { console.log(`bar() ${data}`) otherFun() } function otherFun() { console.log('otherFun()') } window.myModule = { foo, bar } })(window, jQuery)
<!-- 引入的js必须有一定顺序 --> <script type="text/javascript" src="jquery-1.10.1.js"></script> <script type="text/javascript" src="module.js"></script> <script type="text/javascript"> myModule.foo() </script>
|
这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显。
模块化的好处
- 避免命名冲突(减少命名空间污染)
- 更好的分离,按需加载
- 更高的复用性
- 更高的可维护性