解决js循环依赖
问题
js 循环依赖,比如模块A
和模块B
都继承自基类模块C
,但是C
中的某些方法会引用到A
或者B
,这时候A
和C
,B
和C
就是相互依赖的关系。在 ts 中经常会导入模块取类型,相互引用就很常见。
以下代码展示了这种循环依赖关系。
// --- 入口文件 index.js ---
import { C } from "./C";
new C();
// --- 基类模块 C.js ---
import { A } from "./A";
import { B } from "./B";
export class C {}
// --- 子模块 A.js ---
// 这里的import 会报错 Super expression must either be null or a function
import { C } from "./C";
export class A extends C {
constructor() {
super("");
}
}
// --- 子模块 B.js ---
import { C } from "./C";
export class B extends C {
constructor() {
super("");
}
}
这里有一个简单的示例,演示循环引用后报错无法执行
解决方案
建一个额外的公共模块,用来将所有的模块导入进来,再到导出去。如果一个模块要用其他模块的时候,就从这个公共模块中导入进来使用,相当于做一个中转站。
// --- 入口文件 index.js ---
import { C } from "./common";
new C();
// --- 公共模块导出文件 common.js ---
// 注意这里export * from "./C";一定要写在顶部,因为C模块是被A和C依赖的模块,需要优先缓存
export * from "./C";
export * from "./A";
export * from "./B";
// --- 基类模块 C.js ---
import { A } from "./common";
import { B } from "./common";
export class C {}
// --- 子模块 A.js ---
// 这里的import 会报错 Super expression must either be null or a function
import { C } from "./common";
export class A extends C {
constructor() {
super("");
}
}
// --- 子模块 B.js ---
import { C } from "./common";
export class B extends C {
constructor() {
super("");
}
}
这里有一个简单的示例,演示使用公共模块导出后解决循环引用问题
评论