我在JavaScript应用程序中使用ES6模块。源代码是用webpack和babel编译的。这是文件的缩短版本,这会给我带来麻烦:
export const JUST_FORM = 0;
export const AS_PAGE = 1;
console.log(AS_PAGE); // **
export default function doSomething(mode = AS_PAGE) {
console.log(mode);
console.log(JUST_FORM);
}
我正如您期望的那样使用此功能。
import doSomething, { AS_PAGE } from './doSomething'
console.log(AS_PAGE);
doSomething();
当我运行该应用时,它会打印三次undefined
并且仅打印一次AS_PAGE
console.log
,标记为**
。但是,这是最后打印的!它表明:
AS_PAGE
常量(用作doSomething
函数的默认参数)在定义函数时未定义。JUST_FORM
时未定义doSomething
常量。AS_PAGE
常量。显然,这里发生的事情是只有default
导出被解析和评估,文件的其余部分将被忽略,直到稍后。我在我的应用程序中的几个不同位置导入此文件(此时此刻非常大),并且在某些时候这些值实际可用。从控制台输出来看,这是时间问题,但它可能有不同的原因。显然,我在所有地方都以完全相同的方式进行导入。
无论如何,我已经编写了我的整个应用程序,并假设一旦我导入了某些内容,它就会立即可用,我可以在我的代码中使用它。我(简要地)阅读了ES6模块应该如何工作,我还没有找到任何可以证明这个假设错误的东西。它一直在努力。
另请注意,当我使用webpack-dev-server
运行它或将其编译为单个包时,行为是相同的。
这种行为是否真的正确?可能对此负责的是什么?
答案 0 :(得分:28)
正如评论中所建议的,这里的答案是循环依赖。
问题中提供的代码中实际上没有循环依赖(因为它只是简化的代码片段),但症状非常清楚。
循环依赖的最简单的例子是文件A导入文件B而文件B导入A.不幸的是,有时难以检测到这个问题的是圆圈可以任意大,跨越大量文件。
ES6支持循环依赖,当一个人足够小心时可以使用它们。然而,我在这里得到的结论是,循环依赖通常是糟糕的设计决策的标志。这正是我的情况。