568 node之JavaScript模块化:exports,module.exports,import,对象的引用赋值,require查找规则,export、import关键字,CommonJS的加载过程,ES Module加载过程
什么是模块化呢?
早期的JavaScript
没有模块化带来很多的问题
CommonJS和Node
案例设定
exports导出
【exports默认是空对象{}。】
bar.js
// 就是一个模块
// 1.模块内部定义东西
const age = 18;
let message = "my name is why";
function sayHello(name) {
console.log("Hello " + name);
}
// 2.测试其他地方的修改
// setTimeout(() => {
// exports.name = "james";
// }, 1000);
// setTimeout(() => {
// console.log(exports.name);
// }, 2000);
// 通过exports导出内容
// exports.name = name;
// exports.age = age;
// exports.sayHello = sayHello;
// 测试自己内部进行修改对其他地方的影响
// setTimeout(() => {
// module.exports.name = "哈哈哈";
// console.log(exports.name);
// }, 1000);
// 本质上是module.exports在导出
// 导出一个对象类型的引用传递案例分析(内存画图)
let uname = "666";
const info = {
name: 'hahah'
}
// 异步的宏任务
// 导出时是基本类型时,没有影响;引用类型,就会修改对象中的属性值
setTimeout(() => {
uname = "777";
info.name = "11111111";
}, 1000);
// 先执行下面的同步任务,再执行上面的异步的定时器宏任务
// 导出时是基本类型,没有影响;引用类型,就会修改对象中的属性值
module.exports = {
uname,
info: info,
age: 123,
sayHello(name) {
console.log("你好" + name);
}
}
// exports和module.exports之间有什么关系呢?
// 导出一个新的对象, 对导出的内容的影响: 不带exports玩了
// module.exports = {
// };
main.js
/**
* Node中实现CommonJS的本质就是对象的引用赋值
* exports {name, age, sayHello}
*/
// bar = {name, age, sayHello}
const bar = require('./bar');
// 同步任务
console.log(bar.uname); // 666,没有变成777
console.log(bar.info.name); // hahah
console.log(bar.age); // 123
bar.sayHello("kobe"); // 你好kobe
// 异步的宏任务
setTimeout(() => {
// 说明导出时是基本类型时,没有影响;引用类型,就会修改对象中的属性值
console.log(bar.uname); // 666,没有变成777
console.log(bar.info.name); // hahah 变成了 111111
}, 2000);
// setTimeout(() => {
// bar.name = "哈哈哈";
// }, 1000);
// console.log(name);
// console.log(age);
// sayHello("james");
// const obj = {
// name: "why",
// age: 18
// }
// const info = obj;
// const info = {
// name: "why",
// age: 18
// }
// const obj = info;
// obj.name = "kobe";
// console.log(info.name); // kobe
理解对象的引用赋值
画图解析赋值的过程
它们实际上是一个浅层拷贝
module.exports又是什么?
改变代码发生了什么
require细节
先在当前文件所在目录下的node_modules下找,找不到,就往上一层目录下的node_modules下找,以此类推,直到根目录下的node_modules。
模块的加载过程
模块的加载过程是同步。
bar.js
let uname = "why";
console.log(uname);
uname = "hhaha";
console.log(uname);
console.log(module.loaded) // false
foo.js
require('./bar');
console.log(module.loaded) // false
main.js
// 加载过程是同步
require('./bar');
require('./foo');
console.log("main中的代码被执行");
console.log(module.loaded) // false
模块的循环引入
// 结果
main
aaa
ccc
ddd
eee
bbb
aaa.js
console.log('aaa');
require('./ccc');
bbb.js
console.log('bbb');
require('./ccc');
ccc.js
console.log('ccc');
require('./ddd');
ddd.js
console.log('ddd');
require('./eee');
eee.js
console.log('eee');
// require('./bbb')
CommonJS规范缺点
AMD规范
require.js
CMD规范
SeaJS的使用
认识 ES Module
案例代码结构组件
export关键字
import关键字
Export和import结合使用
default用法
import函数
CommonJS的加载过程
ES Module加载过程