问题描述
我在我的JavaScript应用程序中使用ES6模块。来源是用webpack和babel编译的。这是一个缩短版本的文件,导致我麻烦:c $ c $ function $,在定义函数时没有定义。
显然,这里发生的是只有 / code> export被解析和评估,文件的其余部分将被忽略。我在我的应用程序的几个不同的地方导入这个文件(这个时候很大),在某些时候这些值实际上是可用的。从控制台输出判断,这是时间的问题,但是有可能是有其他原因。显然,我在所有地方都做了完全一样的导入。
无论如何,我写了我的整个应用程序,假设一旦我导入了一些东西,就立即可用,我可以在我的代码中使用它。我阅读(简要地)了解ES6模块应该如何工作,我没有发现任何证明这个假设是错误的。而且一直工作到现在为止。
另请注意,当我使用 webpack-dev-server 或将其编译为单个包。
这个行为是否正确?
正如在评论中所建议的,这里的答案是循环依赖性。
问题中提供的代码实际上没有循环依赖关系(因为它只是一个简化的代码段),但症状非常清楚。 p>
循环依赖的最简单的例子是文件A导入文件B和文件B导入A.不幸的是,有时候这个问题难以检测的是,圆可以是任意的大量的,跨越大量的文件。
ES6中支持循环依赖关系,当您足够小心时,可以使用它们。然而,我在这里的外卖是循环依赖通常是错误的设计决定的标志。这正是我的情况。
I use ES6 modules in my JavaScript application. The sources are compiled with webpack and babel. This is a shortened version of the file that causes me trouble:
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); }
I use this functionality just as you would expect.
import doSomething, { AS_PAGE } from './doSomething' console.log(AS_PAGE); doSomething();
When I run the app, it prints three times undefined and only once the expected value AS_PAGE which is the console.log marked with **. However, this is printed last! It shows that:
- The AS_PAGE constant, when used as default parameter for the doSomething function`, is not defined at the moment of defining the function.
- The JUST_FORM constant is not defined when doSomething is called.
- The AS_PAGE constant is not defined when explicitly imported.
Apparently, what's happening here is that only the default export gets parsed and evaluated and the rest of the file is ignored until later. I import this file on several different places in my app (which is quite large at this moment) and at some point those values become actually available. Judging from the console output, it's matter of time, but it is possible that it has a different reason. Obviously, I do the importing exactly the same way in all places.
Anyway, I've written my whole application with the assumption that once I import something, it is immediately available and I can use it in my code. I read (briefly) about how ES6 modules should work and I haven't found anything that would prove this assumption wrong. And it has been working until now.
Also note, that the behavior is the same when I run it with webpack-dev-server or compile it to a single bundle.
Is this behavior really correct? What might be responsible for it?
As suggested in the comments, the answer here are circular dependencies.
There is actually no circular dependency present in the code provided in the question (because it's just a simplified snippet of code) but the symptoms are very clear.
The simplest example of a circular dependency is when file A imports file B and file B imports A. Unfortunately, what makes this issue hard to detect sometimes is that the circle can be arbitrarily large, spanning over a huge amount of files.
Circular dependencies are supported in ES6 and they can be used when one is careful enough. However, my takeaway here is that circular dependencies are very often a sign of bad design decisions. Which was exactly my case.
这篇关于ES6模块:导入的常量首先未定义;他们以后可以使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!