CommonJS 和 ES6 module

本文主要自己觉得要记录的点记录下来,不耽误大家时间,会持续更新。

Module对象

Module {
  id: 'xxx/demo/1.js', //加载文件的绝对路径
  path: 'xxx/demo',// 加载文件所在目录的绝对路径
  exports: [Function (anonymous)],
  filename: 'xxx/demo/1.js',加载文件的绝对路径
  loaded: false,// 是否加载完成
  children: [],// 子模块
  paths: [
    '/xxx/xxx/xxx/xxx/xxx/src/pages/demo/node_modules',
    '/xxx/xxx/xxx/xxx/node_modules',
    '/xxx/xxx/xxx/node_modules',
    '/xxx/xxx/node_modules',
    '/xxx/node_modules',
    '/node_modules'
  ]
}

CommonJS加载一次之后会缓存文件

加载过程

(function(exports, require, module, __dirname, __filename){
	var load = function (exports, module) {
		const aa = require('./demo);
		const result = aa;
		module.exports.result = result;
	    return module.exports;
	};
	var exported = load(module.exports, module);
	save(module, exported);
})

CommonJS返回的是对象引用之后,在A地方修改后,会影响到B地址的加载结果。

CommonJS 模块同步加载并执行模块文件,ES6 模块提前加载并执行模块文件,ES6 模块在预处理阶段分析模块依赖,在执行阶段执行模块,两个阶段都采用深度优先遍历,执行顺序是子 -> 父。

CommonJS 父->子->父 (父加载 遇到引用了子,加载子,子加载完跳回父继续加载)

ES6 module 子->父 (父里面引用子,加载子,子里面引用子,加载子...加载完再一步一步返回上一级加载)

2 与 exports 相比,module.exports 有什么缺陷 ?

答:module.exports 当导出一些函数等非对象属性的时候,也有一些风险,就比如循环引用的情况下。对象会保留相同的内存地址,就算一些属性是后绑定的,也能间接通过异步形式访问到。但是如果 module.exports 为一个非对象其他属性类型,在循环引用的时候,就容易造成属性丢失的情况发生了。

这句话一直不理解直到看了下面这个例子:

a.js

const getMes = require('./b.js');
console.log('我是a文件');
// /**
//  * @description: 写法一
//  */
// exports.say = function () {
//   const message = getMes();
//   console.log(message);
// };
/**
 * @description: 写法二
 */
const say = function () {
  const message = getMes();
  console.log(message);
};
module.exports = say;

b.js

const say = require('./a');

const obj = {
  age: 10,
};

console.log('我是b文件', say);
setTimeout(() => {
  console.log('setTimeout...', say);
}, 10);
module.exports = function () {
  return obj;
};

main.js

require('./a.js');
require('./b.js');

写法1

b中第一次倒入的a模块对象say是一个空对象,然后a加载完毕exports(也就是b里面那个空对象的引用)赋值了一个属性say。所以setTimeout可以拿到属性say

写法2

 

b中第一次倒入的a模块对象say是一个空对象,然后a加载完毕module.exports重新赋值了一个新的对象,那之前的对象(也就是b中导入的那个对象)就应用是一个空对象。那么setTimeout里面自然也是一个空对象。如果在setTimeout重新导入a模块就能拿到改变之后的a模块。

//TODO。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值