记一次js循环依赖
起因
由于为了Vscode查找文件方便,我有时会将组件直接以 Abc.tsx
的方式命名,然后用index.ts文件统一导出整个文件/模块下的所有文件。
本来这是很常见的操作,然后今天在写代码的时候却引发了很大的报错,我要导入的一个enum总是显示为undefined TypeError: Cannot read properties of undefined (reading 'all')
解决方案
尝试console.log
debugger,等方案,却怎么都无法解决。
直接使用string
后来,不通过enum,直接使用string,就可以了
什么是循环依赖
es6模块加载机制
JavaScript 在解析模块时会提前创建变量,但只在执行到相应的代码时才初始化它们
所以,如果产生的循环依赖,先执行的模块依赖的模块还未被初始化,会导致undefined
报错。
举个例子
// moduleA.js
import { valueB } from './moduleB';
export const valueA = 'A';
console.log('In moduleA:', valueB); // 输出 "In moduleA: undefined"
// moduleB.js
import { valueA } from './moduleA';
export const valueB = 'B';
console.log('In moduleB:', valueA); // 输出 "In moduleB: A"
在这个例子中,moduleA 导入了 moduleB,而 moduleB 导入了 moduleA。当解析这两个模块时,JavaScript 首先创建了 valueA 和 valueB 变量,但尚未初始化它们。然后,它按顺序执行模块的代码。
当执行 moduleA 时,它试图访问 valueB,但此时 valueB 尚未初始化,因此输出 undefined。接下来,执行 moduleB 时,它访问 valueA,此时 valueA 已经被初始化为 'A',因此输出 'A'。
在这里也吐槽一下,之前的golang的时候编译器会有循环依赖的检查,ts尽然检查不出来(也有可能是我没开)。
*** 所以最后的解决方案是,直接通过目标文件引入,而不是通过index.ts, 也就是打破循环依赖***
引以为戒
所以以后还是不要用统一的index.ts,而是按需导入
不过这也产生了一个矛盾,怎么样能不产生循环依赖,又能在Vscode更好的全局搜索呢。