JS模块化

Yuyang 前端小白🥬

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() // foo() other data

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
// index.html文件
<script type="text/javascript" src="module.js"></script>
<script type="text/javascript">
myModule.foo()
myModule.bar()
console.log(myModule.data) //undefined 不能访问模块内部数据
myModule.data = 'xxxx' //不是修改的模块内部的data
myModule.foo() //没有改变
</script>

// module.js文件
(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 } //ES6写法
})(window)

// foo() www.baidu.com
// bar() www.baidu.com
// otehrFun()
// undefined
// foo() www.baidu.com

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
// module.js文件
(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)

// index.html文件
<!-- 引入的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>

这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显。

模块化的好处

  • 避免命名冲突(减少命名空间污染)
  • 更好的分离,按需加载
  • 更高的复用性
  • 更高的可维护性

引入多个
访问人数 总访问量
Hexo 驱动 主题 Redefine v2.6.4