1.为什么要有模块化
- 在网页开发的早期,js制作作为一种脚本语言,做一些简单的表单验证或动画实现等,那时候的代码还是很少的。
- 随着ajax异步请求的出现,慢慢的形成了前后端分离客户端需要完成的事情越来越多,代码量也与日俱增为了应对代码量的剧增,我们通常会将代码组织在多个js文件中,进行维护。但是这种维护方式,依然不能避免一些灾难性的问题。
- 比如全局变量同名问题:a文件中具有flag变量,b文件中也具有flag变量,如果此时不知道a文件中也使用flag变量的话,就会导致卡很长时间的bug。(看下面例子)
- 另外,这种代码编写方式对js文件的依赖顺序几乎是强制性的。
- 但是当js文件过多,比如有几十个的时候,弄清楚他们的顺序是一件比较耗时的事情。
- 而且即使弄清楚顺序,也不能避免上面出现的这种尴尬问题的发生。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
项目组长
小明
小红
-->
<script src="main.js"></script>
<script src="aaa.js"></script>
<script src="bbb.js"></script>
<script src="mmm.js"></script>
</body>
</html>
aaa.js
// 小明
var name = "小明";
var age = 22;
function sum(num1, num2) {
return num1 + num2
}
var flag = true;
if(flag) {
console.log('sum(20, 30)', sum(20, 30));
}
bbb.js
// 小红
var name = "小红";
var flag = false;
console.log("name====", name);
mmm.js
if(flag) {
console.log('小明的另一个文件也需要输出!!!');
}
2.模块化的雏形
众所周知:闭包能够有效的解决变量同名问题,因为闭包会形成自己的作用域。
下面是修改后的文件(ps:小明开发有aaa.js、mmm.js文件;小红开发有bbb.js)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
项目组长
小明
小红
-->
<script src="main.js"></script>
<script src="aaa.js"></script>
<script src="bbb.js"></script>
<script src="mmm.js"></script>
</body>
</html>
aaa.js
// 小明
var moduleA = (function() {
var name = "小明";
var age = 22;
function sum(num1, num2) {
return num1 + num2;
}
var flag = true;
if(flag) {
console.log('sum(20, 30)', sum(20, 30));
}
})()
bbb.js
// 小红
var moduleB = (function() {
var name = "小红";
var flag = false;
console.log("name====", name);
})();
mmm.js
if(moduleA.flag) {
// 1. 小明想使用他自己的flag
// 2. 使用sum函数
}
aaa.js
// 小明
var moduleA = (function() {
var name = "小明";
var age = 22;
const obj = {}; // 导出的对象
function sum(num1, num2) {
return num1 + num2;
}
var flag = true;
if(flag) {
console.log('sum(20, 30)', sum(20, 30));
}
obj.flag = flag;
obj.sum = sum;
return obj;
})()
bbb.js
// 小红
var moduleB = (function() {
var name = "小红";
var flag = false;
var tip = "标识是使用小红的变量";
var obj = {}; // 导出的对象
obj.name = name;
obj.flag = flag;
obj.tip = tip;
return obj;
})();
mmm.js
// 小明
if(moduleA.flag) {
// 1. 小明想使用他自己的flag
console.log('使用aaa文件中的flag', moduleA.flag);
// 2. 使用sum函数
console.log("moduleA.sum(100, 88)====", moduleA.sum(100, 88));
}
nnn.js
console.log('使moduleA的flag', moduleA.flag);
console.log('使moduleA的sum', moduleA.sum(66,66));
console.log('使moduleB的flag', moduleB.flag);
console.log('使moduleB的tip', moduleB.tip);
3.ES6的模块化实现
众所周知,前端模块化的方式有很多种,比如CommonJS、AMD、CMD以及Es6模块的模块化,这里主要介绍ES6的模块
3.1 export的基本使用
export 指令用于导出变量,比如下面的代码
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
项目组长
小明
小红
-->
<script src="aaa.js" type="module"></script>
<script src="bbb.js" type="module"></script>
<script src="mmm.js" type="module"></script>
</body>
</html>
要使用es6的导入导出模板,则需要再script标签上添加type="module"属性
aaa.js
// 小明
var name = "小明";
var age = 22;
function sum(num1, num2) {
return num1 + num2;
}
var flag = true;
if(flag) {
console.log('sum--aaa', sum(20, 30));
}
// 导出方式1
export { flag, sum }
// 导出方式2
// 在定义变量的时候直接导出
export var num1 = 1000;
export var height = 1.88;
mmm.js
// 1.导出{}中定义的变量
import { flag, sum } from "./aaa.js"
if(flag) {
console.log('小明真是个天才哈哈哈哈哈!!');
console.log('sum--mmm', sum(90, 9));
}
// 2. 直接导入export定义的变量
import { num1, height } from "./aaa.js"
console.log("height====", height);
console.log("num1====", num1);
3.2导出函数/类
aaa.js
// 导出函数/类
export function mul(num1, num2) {
return num1*num2
}
export class Person {
constructor(name, age) {
this.name = name;
this.age = age
}
run() {
console.log(`${this.age}岁的${this.name}在奔跑`);
}
}
mmm.js
// 3. 导入export中的function/class
import { mul, Person } from "./aaa.js"
console.log("mul====", mul(30, 40));
new Person("大爷", 18).run();
3.3 export default 默认导出
aaa.js
const address = "广州市";
export default address; // 切记:默认导出只能导出一个,不能导出多个
mmm.js
// 4. 导入 export default
import address from "./aaa.js"; // 切记默认导入不需要{}
console.log("address====", address);
3.4 统一全部导入
import * as aaa from "./aaa.js"
console.log('height-统一导入的使用', aaa.height);
console.log('sum-统一导入的使用', aaa.sum(1,1));
console.log('mul-统一导入的使用', aaa.mul(2,1));
标签:console,log,模块化,前端,js,flag,var,sum
From: https://www.cnblogs.com/Qqhx/p/17785399.html