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加载过程



画图解析赋值的过程


Node对ES Module的支持


CommonJS和ES Module交互

















原文地址:https://www.cnblogs.com/jianjie/p/14221004.html