CommonJS和ES6 Module分别如何处理循环依赖的问题?
前篇(CommonJS和ES6 Module的区别):juejin.cn/post/695936…
前言:一般来说工程中应该尽量避免循环依赖的产生,因为从软件设计的角度来说,单向的依赖关系更加清晰,而循环依赖则会带来一定的复杂度。
- 但工程的复杂度上升到足够规模时,就容易出现隐藏的循环依赖关系。简单来说,A和B两个模块之间是否存在直接的循环依赖关系是很容易被发现的。但实际情况往往是A依赖于B,B依赖于C,C依赖于D,最后绕了一大圈,D又依赖于A。当中间模块太多时就很难发现A和B之间存在着隐式的循环依赖。
实际代码举例
目录结构:
├── main.js
├── bar.js
├── aaa.js
commonjs中 循环依赖的情况(注释内有解析)
// main.js
const bar = require('./bar.js')
console.log('当前是main.js内:', bar) // {}
module.exports = '在main.js内'
// bar.js
const main = require('./main.js')
console.log('当前是bar.js内:', main)
module.exports = 'bar.js内'
// 执行 node ./main.js , 输出:
当前是bar.js内: {} // 解析:执行到bar.js内时,main.js还没有执行完,就没有东西导出,会默认导出空对象
当前是main.js内: bar.js内
es6 module中 循环依赖的情况(注释内有解析)
// main.js
import bar from './bar.js'
console.log('当前是main.js内:', bar)
export default '在main.js内'
// bar.js
import main from './main.js'
console.log('当前是bar.js内:', main)
export default 'bar.js内'
// 执行 webpack-dev-server xx 启服务去执行 入口是main.js , 输出:
当前是bar.js内: undefined // 解析:编译到bar.js内时,main.js还没有编译完,就没有东西编译映射到main这个变量上去,就是undefined
当前是main.js内: bar.js内
解决方法
用es6 module:因为他的值的动态映射的,可以在模块都解析完后,得到变更后的状态
具体方法举例:
方法一: 异步,比如setTimeout
// main.js
import bar from './bar.js'
console.log('当前是main.js内:', bar)
export default '在main.js内'
// bar.js
import main from './main.js'
console.log('当前是bar.js内:', main)
setTimeout(() => {
console.log('当前是bar.js内:', main) // 这里能输出,因为main.js已经解析完了,(export default '在main.js内')这一行解析完了
})
export default 'bar.js内'
// 执行 webpack-dev-server xx 启服务去执行 入口是main.js , 输出:
当前是bar.js内: undefined
当前是main.js内: bar.js内
当前是bar.js内: 在main.js内
方法二:导出一个函数
// main.js
import a from './a.js'
a()
// a.js
import b from './b.js'
export default function () {
console.log('当前是a.js内:', b())
}
// b.js 导出一个函数
import a from './a.js'
export default function () {
console.log('当前是b.js内:', a())
}
码字不易,点赞鼓励!!