如何正确处理类导入中的循环依赖与相互递归?
如何正确处理导入中的循环依赖?
先看以下代码场景:
base.ts
import * as all from './all' export class Base {} export class Container extends Base { parse(){ console.log(all) } }
all.ts
import { Base, Container } from './base'; export class A extends Base {} export class B extends Container {}
main.ts
import { Container } from './base'; new Container().parse();
使用Rollup打包后生成的代码如下:
class A extends Base { } class B extends Container { } const all = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, A, B }, Symbol.toStringTag, { value: "Module" })); class Base { } class Container extends Base { parse() { console.log(all); } } new Container().parse();
这段打包代码将class B extends Container放在了class Container的定义之前,而class声明无法像函数一样被提升,运行时会直接报错。
当业务逻辑必须保留这种循环依赖结构时,打包工具的排序规则可能导致这类问题。以下是两种临时解决方案作为最后手段,确保代码正常运行:
方案一:利用函数提升规避顺序问题
class A extends f() {} class C extends f() {} var _B; // 仅var有效,let会失效 function f() { // 确保返回的类具有相同标识 if (!_B) { _B = class B { static id = Math.random(); }; } return _B; }
原理:函数声明会被优先提升,当类继承调用函数时,函数已经存在,后续再初始化目标类,保证继承时能获取到正确的类引用。
方案二:强制指定依赖解析顺序
import './all' // 提前导入all模块,调整解析顺序 import { Container } from './base'; new Container().parse();
原理:通过提前导入all模块,强制打包工具调整循环依赖的解析顺序,确保被继承的类先被定义。
内容的提问来源于stack exchange,提问作者Guichi
相关产品推荐
相关产品推荐

