Skip to content

fix(core): share generated ids across bundles - #2141

Open
g1f9 wants to merge 1 commit into
VisActor:mainfrom
g1f9:fix/shared-generator-state
Open

g1f9 wants to merge 1 commit into
VisActor:mainfrom
g1f9:fix/shared-generator-state

Conversation

@g1f9

@g1f9 g1f9 commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

🤔 这个分支是...

  • Bug fix
  • 测试 case 更新

🔗 相关 issue 连接

暂无。

🐞 Bugserver 用例 id

暂无。

💡 问题的背景&解决方案

VRender 已通过 Symbol.for(...) 在同一页面的多个 bundle 之间共享 application、legacy binding context 和 shared app,但 Generator.auto_increment_id 仍是每个 bundle 私有的静态变量。

当 bundle A 先初始化 legacy LayerService、bundle B 随后创建 shared app 时,shared app 的 StageFactory 可能来自 B,而 Stage 使用的全局 LayerService 来自 A。此时 Stage 与 Layer 分别从两个独立计数器取 _uid;一旦数值相同,Node.appendChild 会把两个不同对象误判为同一节点并返回 null,导致 Stage 没有 default layer。上层 VChart 随后在 Compiler.initView() 调用 stage.defaultLayer.appendChild(rootGroup) 时抛出:

TypeError: Cannot read properties of null (reading 'appendChild')

真实 UMD 复现路径:

  1. 加载第一份 @visactor/vrender bundle,并创建一次 Stage,使全局 legacy binding context 持有该 bundle 的 LayerService。
  2. 加载第二份相同版本的 bundle,并通过 acquireSharedVRenderApp() 创建 shared app。
  3. 让两份 bundle 的 Generator 在下一次 Stage/Layer 创建时产生相同 _uid。
  4. 第二份 bundle 创建 Stage;其 Stage 来自 bundle B,Layer 来自 bundle A。
  5. 修复前得到 stage.childrenCount === 0、stage.defaultLayer === null,继续执行 VChart 的 root group 挂载即可得到上述异常。

本次把 Generator 计数状态放到 globalThis[Symbol.for('@visactor/vrender-core/generator-state')],与现有跨 bundle runtime 状态的共享方式保持一致。每次生成 ID 仍只执行一次对象属性自增,不增加图形树热路径的遍历或对象分配。

新增回归测试覆盖:

  • 两个隔离模块实例从同一个 ID 序列继续递增。
  • 两个隔离模块实例创建的 Node 保持不同 _uid,并能正常建立父子关系。

📝 Changelog

Language Changelog
🇺🇸 English Fix missing Stage default layers caused by generated node ID collisions across multiple VRender bundles.
🇨🇳 Chinese 修复多份 VRender bundle 共存时节点 ID 碰撞导致 Stage 缺少默认 Layer 的问题。

☑️ 自测

  • generator.test.ts:5 个测试通过;新增用例已确认在修复前失败。
  • rush run -p @visactor/vrender-core -s compile 通过。
  • 修改文件 ESLint 与 git diff --check 通过。
  • 文档:不需要修改,行为属于内部 ID 唯一性修复。
  • Demo:不需要修改,已有真实双 UMD bundle 复现。
  • TypeScript 类型定义:不需要修改。
  • Changelog:已提供。

🚀 Summary

copilot:summary

🔍 Walkthrough

copilot:walkthrough

Co-authored-by: TRAE CLI <traecli@bytedance.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants