写这篇文章的起因是源于和同事的一次讨论, 同事的周报上说在写 React 组件的时候, A 组件 Import 了 B 组件, 同时在 B 组件中也 Import 了A 组件,此情况就形成了循环依赖,在 A 组件中引入的 B 组件为 undefined。但是在我之前的印象中( #16) ,此时的 B 组件应该为空对象 {} 。
一言不合,看看 babel 把 ES6 的 Module 翻译成什么:
// =================
// a.js
// =================
import b from './b'
function foo() {
b.bar();
}
export default foo
// =================
// b.js
// =================
import a from './a'
console.log(a)
上面一段代码,如果是 node 的写法,在读取 a.js 的时候就被 cache 为一个空对象了,此时在 b 中读取a一定会是一个空对象,但是通过babel-cli把a.js和b.js翻译成ES5` 之后再看看:
写这篇文章的起因是源于和同事的一次讨论, 同事的周报上说在写 React 组件的时候, A 组件 Import 了 B 组件, 同时在 B 组件中也 Import 了A 组件,此情况就形成了循环依赖,在 A 组件中引入的 B 组件为
undefined
。但是在我之前的印象中( #16) ,此时的 B 组件应该为空对象{}
。一言不合,看看 babel 把 ES6 的 Module 翻译成什么:
上面一段代码,如果是
node
的写法,在读取a.js
的时候就被cache
为一个空对象了,此时在b 中读取
a一定会是一个空对象,但是通过
babel-cli把
a.js和
b.js翻译成
ES5` 之后再看看:从上面两段代码可以看到 babel 把
export default foo
转成exports.default = foo
, 在b.bundle.js
中根据 #16 中分析的可以知道_a
的值为{}
,所以此时_a2.default
的值为_a.default
, _a 为{}
, 那么{}.default
是undefined
。其实如果按照 ES6 的标准,ES6 module 的出现就天然的解决了循环依赖的问题,babel 对 ES6 的module 的支持还是有些问题的,只是简单的翻译成 common.js 的方式。😄