为什么迫切需要js模块化
随着2006年ajax概念被提出,前端的业务的业务越来越多,代码也越来越多,并逐渐发展成为前后端分离的状态,出现了专门的前端攻城狮。
但是随着代码的增多,也随之衍生很多问题。
1.早期的js代码:
- common.js
let mode = "single";
function operation(a, b){
return a + b;
}
//other functions...
- main.js
function operation(a, b){
return a * b;
}
//other functions...
- main.html 中同时引入两个js文件
<script src="common.js"></script>
<script src="main.js"></script>
<script type="text/javascript">
var result = operation(5,5);
console.log(result); //25
</script>
- 由代码可以发现common.js中的operate函数被main.js中的operate函数覆盖掉了,这种现象称为Global全局变量污染,容易引起命名冲突。
改良版本1:命名空间模式
- common.js
let common = {
data: 'single',
operation1(a, b) {
return a + b;
},
operation2() {
return a * b;
},
}
- main.js
let main = {
operation1(a, b){
return a * b;
}
//,other functions......
}
- test.html
<script src="common.js"></script>
<script src="main.js"></script>
<script type="text/javascript">
var result = common.operation(5,5);
common.data = "changed" //私有数据被改变,数据不安全
console.log(result); //25
</script>
- 简单对象封装,减少了全局变量,但是数据依然不安全
改良版本2:IIFE模式
- common.js
(function (window) {
//数据
let data = 'test'
//操作数据的函数
function foo() { //用于暴露有函数
console.log(`foo() ${data}`)
}
function bar() {//用于暴露有函数
console.log(`bar() ${data}`)
otherFun() //内部调用
}
function otherFun() { //内部私有的函数
console.log('otherFun()')
}
//暴露行为
window.myModule = {foo, bar}
})(window)
- test.html
<script type="text/javascript" src="common.js"></script>
<script type="text/javascript">
myModule.foo()
myModule.bar()
//myModule.otherFun() //myModule.otherFun is not a function
console.log(myModule.data) //undefined 不能访问模块内部数据
myModule.data = 'xxxx' //不是修改的模块内部的data
myModule.foo() //没有改变
</script>
- 说明:
- IIFE模式: 匿名函数自调用(闭包)
- IIFE : immediately-invoked function expression(立即调用函数表达式)
- 作用: 数据是私有的, 外部只能通过暴露的方法操作
- 问题: 如果当前这个模块依赖另一个模块怎么办?
IIFE模式增强
- 引入jquery到项目中
- common.js
(function (window, $) { //数据 let data = 'atguigu.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)
- test.html
<script type="text/javascript" src="jquery-1.10.1.js"></script> <script type="text/javascript" src="common.js"></script> <script type="text/javascript"> myModule.foo() </script>
- 说明
- IIFE模式增强 : 引入依赖
- 这就是现代模块实现的雏形
- common.js
- 页面加载多个js的问题
- 页面:
<script type="text/javascript" src="module1.js"></script> <script type="text/javascript" src="module2.js"></script> <script type="text/javascript" src="module3.js"></script> <script type="text/javascript" src="module4.js"></script>
- 说明
- 一个页面需要引入多个js文件
- 问题:
- 请求过多
- 依赖模糊
- 难以维护
- 这些问题可以通过现代模块化编码和项目构建来解决