从这学期开始学了vue3,并且写了一些项目,但是到现在还没搞清楚什么时候用
export default,什么时候用export,可能我当时JavaScript基础学的不扎实。
下面记录一下ES6模块化是什么并且怎么用。
视频建议看(尚硅谷天禹老师)的视频:www.bilibili.com/video/BV13W…
1.什么是模块化
- 将程序按照一定的规则拆分成多个文件。
- 拆分出来的每个文件就是一个
模块。 - 同时通过一些手段,可以把
模块内的指定数据交出去,供其他模块复用。
这个很好理解,我当时写个人博客项目的时候也是根据功能的不同,把前后端数据交互的api分成了好几个js文件:
下面举几个例子:
category.js
tag.js
你觉得把这两个js文件放到一个.js文件好呢还是分成两个.js文件好呢,当然是后者。
2.为什么需要模块化
- 如果不进行合理的模块化,导致
全局污染问题
比如有两个js文件,school.js和student.js:
school.js
const name = 'xxx学院'
const slogan = '学以致用,快乐成长'
function getTel() {
return '010-12345678'
}
function getCities() {
return ['北京', '上海', '广州', '深圳']
}
student.js
const name = "John"
const motto = "Don't worry, be happy!"
function getTel() {
return "123-456-7890"
}
function getHobby() {
return ["reading", "swimming", "hiking"]
}
在index.js中进行引入:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./student.js"></script>
<script src="./school.js"></script>
</body>
</html>
浏览器控制台已经报错了我:
相当于重复声明了两个变量
name。
- 如果不进行合理的模块化,导致
依赖混乱问题。 - 还会导致
数据安全问题。
3.ES6 MODULES
分别导出和引入所有
分别导出:
很简单,把想导出的东西前面加上export关键字:
export const name = "John"
export const motto = "Don't worry, be happy!"
export function getTel() {
return "123-456-7890"
}
// 这个我不想交出去
function getHobby() {
return ["reading", "swimming", "hiking"]
}
引入所有:
import * as student from './student.js'
console.log(student)
为了让node环境支持ES6 MODULES模块化规范,需要在当前目录下创建一个
package.json文件:
{
"type": "module"
}
node环境输出结果:
浏览器控制台输出结果:
html中导入index.js:需要写type="module"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module" src="./index.js"></script>
</body>
</html>
export统一导出
统一导出用这种格式导出export { name, motto, getTel }。
const name = "John"
const motto = "Don't worry, be happy!"
function getTel() {
return "123-456-7890"
}
function getHobby() {
return ["reading", "swimming", "hiking"]
}
// 统一导出
export { name, motto, getTel }
export default默认导出
注意:export default后面跟的是值,可以导出任意值或者变量
const name = "John"
const motto = "Don't worry, be happy!"
function getTel() {
return "123-456-7890"
}
function getHobby() {
return ["reading", "swimming", "hiking"]
}
// 默认导出
export default 900
导出多个值:
const name = "John"
const motto = "Don't worry, be happy!"
function getTel() {
return "123-456-7890"
}
function getHobby() {
return ["reading", "swimming", "hiking"]
}
// 统一导出多个值
export default { name, motto, getTel }
命名导入
可以通过{ xxx as 被导出的值 }命名导入
什么时候可以命名导入:统一导出和分别导出
student.js
const name = "John"
const motto = "Don't worry, be happy!"
function getTel() {
return "123-456-7890"
}
function getHobby() {
return ["reading", "swimming", "hiking"]
}
// 统一导出
export { name, motto, getTel }
index.js
import { name as stuName, motto as stuMotto, getTel as getStuTel } from './student.js';
console.log(stuName);
console.log(stuMotto);
console.log(getStuTel());
默认导入
默认导出的东西,不用写{}导入,可以直接导入:
student.js
const name = "John"
const motto = "Don't worry, be happy!"
function getTel() {
return "123-456-7890"
}
function getHobby() {
return ["reading", "swimming", "hiking"]
}
// 默认导出
/*export default name*/
// 或者导出多个变量
export default {name, motto, getTel}
index.js
import student from './student.js'
console.log(student)
也可以导入的时候取别的名字:
import studentInfo from './student.js'
console.log(studentInfo)
动态导入
动态导入就是只有需要使用该模块的时候才进行导入。
这个有点像vue-router的路由懒加载,当然vue-router导入的是.vue文件。
student.js
const name = "John"
const motto = "Don't worry, be happy!"
function getTel() {
return "123-456-7890"
}
function getHobby() {
return ["reading", "swimming", "hiking"]
}
export { name, motto, getTel }
在index.js中动态导入:
const btn = document.querySelector('#btn')
// 需要异步导入,因为导入是有延迟的
btn.onclick = async () => {
const student = await import('./student.js')
console.log(student)
}
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">获取student信息</button>
<script type="module" src="./index.js"></script>
</body>
</html>
import直接导入
可能项目中我们导入的是一种导入就运行的函数什么的,这个时候我们可以直接导入:
random.js
console.log(Math.random())
在index.js中直接导入:
// 直接导入,不用写什么from等语句
import './random.js'
写过vue的朋友门这个应该很熟悉,比如main.js:
这里有几个.css文件进行了直接导入。
COMMONJS
CommonJS (CJS) 是 Node.js 采用的模块系统,它的设计初衷是用于服务器环境。
在 CommonJS 中,每个文件都是一个独立的模块。这个模块内部有一个 module 对象,module 对象上有一个 exports 属性,它就是我们要导出的东西。
直接赋值导出
// myUtils.js
// 导出一个函数
module.exports = function(a, b) {
return a + b;
};
// 或者导出一个对象
module.exports = {
name: 'utils',
add: function(a, b) {
return a + b;
},
subtract: function(a, b) {
return a - b;
}
};
导入 (require)
使用 require() 函数来导入其他模块,并接收 module.exports 导出的值。
// main.js
// 导入整个模块
const addFunction = require('./myUtils.js'); // 导入的是那个函数
const result1 = addFunction(5, 10); // 15
const utils = require('./myUtils.js'); // 假设 myUtils.js 导出的是对象
const result2 = utils.add(5, 10); // 15
console.log(utils.name); // 'utils'
// 导入属性
const constants = require('./myConstants.js');
console.log(constants.PI); // 3.14159
// 使用解构赋值(更简洁)
const { PI, VERSION } = require('./myConstants.js');
console.log(PI); // 3.14159
console.log(VERSION); // '1.0.0'