Skip to content

Conversation

@weareoutman
Copy link
Member

@weareoutman weareoutman commented Sep 17, 2025

依赖检查

组件之间的依赖声明,是微服务组件架构下的重要信息,请确保其正确性。

请勾选以下两组选项其中之一:

  • 本次 MR 没有使用上游组件(例如框架、后台组件等)的较新版本提供的特性。

或者:

  • 本次 MR 使用了上游组件(例如框架、后台组件等)的较新版本提供的特性。
  • 在对应的文件中更新了该上游组件的依赖版本(或确认了当前声明的依赖版本已包含本次 MR 使用的新特性)。

提交信息检查

Git 提交信息将决定包的版本发布及自动生成的 CHANGELOG,请检查工作内容与提交信息是否相符,并在以下每组选项中都依次确认。

破坏性变更是针对于下游使用者而言,可以通过本次改动对下游使用者的影响来识别变更类型:

  • 下游使用者不做任何改动,仍可以正常工作时,那么它属于普通变更。
  • 反之,下游使用者不做改动就无法正常工作时,那么它属于破坏性变更。

例如,构件修改了一个属性名,小产品 Storyboard 中需要使用新属性名才能工作,那么它就是破坏性变更。
又例如,构件还没有任何下游使用者,那么它的任何变更都是普通变更。

破坏性变更:

  • ⚠️ 本次 MR 包含破坏性变更的提交,请继续确认以下所有选项:
  • 没有更好的兼容方案,必须做破坏性变更。
  • 使用了 feat 作为提交类型。
  • 标注了 BREAKING CHANGE: 你的变更说明
  • 同时更新了本仓库中所有下游使用者的调用。
  • 同时更新了本仓库中所有下游使用者对该子包的依赖为即将发布的 major 版本。
  • 同时为其它仓库的 Migrating 做好了准备,例如文档或批量改动的方法。
  • 手动验证过破坏性变更在 Migrate 后可以正常工作。
  • 破坏性变更所在的提交没有意外携带其它子包的改动。

新特性:

  • 本次 MR 包含新特性的提交,且该提交不带有破坏性变更,并使用了 feat 作为提交类型。
  • 给新特性添加了单元测试。
  • 手动验证过新特性可以正常工作。

问题修复:

  • 本次 MR 包含问题修复的提交,且该提交不带有新特性或破坏性变更,并使用了 fix 作为提交类型。
  • 给问题修复添加了单元测试。
  • 手动验证过问题修复得到解决。

杂项工作:

即所有对下游使用者无任何影响、且没有必要显示在 CHANGELOG 中的改动,例如修改注释、测试用例、开发文档等:

  • 本次 MR 包含杂项工作的提交,且该提交不带有问题修复、新特性或破坏性变更,并使用了 chore, docs, test 等作为提交类型。

Summary by CodeRabbit

  • 新功能
    • 引入模板隔离:在非页面根的片段/范围内独立注册与卸载模板,避免跨范围污染,提升复用与调试体验。
    • 支持与函数一同按范围注册模板,并在卸载时同步清理。
  • 体验改进
    • 当作用域缺少模板时,相关自定义元素安全渲染为空,行为更可预期;卸载时清理残留注册。
  • 测试
    • 新增隔离模板存在/缺失场景的用例,验证渲染与清理一致性。

@coderabbitai
Copy link

coderabbitai bot commented Sep 17, 2025

Walkthrough

引入模板隔离机制:增加每根隔离根(Symbol)对应的模板注册与清理;在非页面根创建时注册隔离模板与函数,并在卸载时清理。调整获取模板标签名逻辑以支持隔离上下文。放宽函数注册参数为可选。导出与类签名相应更新,并补充相关测试。

Changes

Cohort / File(s) Summary of modifications
模板隔离核心实现
packages/runtime/src/internal/IsolatedTemplates.ts
新增模块;导出 isolatedTemplateRegistryMapregisterIsolatedTemplates(isolatedRoot, templates);为每个 isolatedRoot 维护 CustomTemplateRegistry(true) 并在注册前清空,按名称注册模板;支持 undefined 模板输入。
根创建与卸载流程接入隔离模板
packages/runtime/src/createRoot.ts
非页面根创建时先注册隔离模板再注册隔离函数;在卸载时从 isolatedTemplateRegistryMap 中清除对应条目。新增相关导入。
模板解析使用隔离上下文
packages/runtime/src/internal/CustomTemplates/expandCustomTemplate.ts
增加从 isolatedTemplateRegistryMapisolatedRoottplTagName 读取模板数据的分支;若无隔离根则保持使用 customTemplates
模板名解析 API 变更与逻辑更新
packages/runtime/src/internal/CustomTemplates/utils.ts, packages/runtime/src/internal/CustomTemplates/utils.spec.ts
getTagNameOfCustomTemplate 签名改为接收 runtimeContext(含 appisolatedRoot);优先从隔离注册表判定;否则基于 runtimeContext.app 进行应用内前缀解析;保留直接在全局 customTemplates 的回退。测试相应更新为传入上下文对象。
渲染器调用适配新签名
packages/runtime/src/internal/Renderer.ts
调用从传 app.id 改为传完整 runtimeContextgetTagNameOfCustomTemplate
自定义模板注册器扩展
packages/runtime/src/CustomTemplates.ts
CustomTemplateRegistry 设为导出类;新增可选构造参数 isolated?: boolean 与私有字段 #isolated;新增 clearIsolatedRegistry() 用于在隔离模式下清空注册表;移除若干无效的 eslint 忽略注释。
隔离函数注册参数放宽
packages/runtime/src/internal/compute/IsolatedFunctions.ts, packages/runtime/src/StoryboardFunctionRegistry.ts
registerIsolatedFunctionsregisterStoryboardFunctionsfunctions 参数改为可选 StoryboardFunction[] | undefined;相应类型导入改为 type-only;逻辑容纳 undefined 情况。
公共导出调整
packages/runtime/src/index.ts
将通配导出改为具名导出:export { customTemplates } from "./CustomTemplates.js";
新增用例验证隔离模板行为
packages/runtime/src/createRoot.spec.ts
新增两条测试:存在/不存在模板时在隔离作用域的渲染结果与清理。

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch steve/v3-isolated-templates

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Pre-merge checks

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ⚠️ Warning PR 描述当前仅粘贴了仓库的描述模板而未填写任何与本次变更相关的实际信息或勾选项,缺少对依赖变更、提交类型(feat/fix/chore)、是否为破坏性变更、变更摘要、测试与验证信息以及迁移说明等必需内容,因此无法评估合规性与影响范围。基于现有内容无法判断此次 MR 是否满足仓库描述模板的要求或需要发布注意事项。 因此本检查项判定为失败,需作者补充后再评估。 请作者在 PR 描述中完整填写模板内容:勾选并说明依赖检查结论或更新的依赖版本,明确提交类型并标注若为破坏性变更需添加 “BREAKING CHANGE” 说明,列出新增/修改的单元测试与手动验证步骤,补充简要变更摘要(包含受影响的文件/模块和迁移建议),然后重新请求审查;补充信息后审查者应核对并标注相应选项以继续合并流程。
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed 标题 "feat(): support isolated templates" 简洁且准确反映了本次 PR 的核心意图——为模板系统增加隔离(isolated templates)支持,能够让审阅者快速识别主要变更点。唯一小瑕疵是空的 scope 括号 "()" 显得不必要且可能被视为噪音或格式不规范,但不影响理解。总体上标题清晰、具体,适合作为变更历史记录的一行摘要。

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for isolated templates in the runtime system, allowing templates to be scoped to specific contexts without affecting the global template registry.

  • Creates isolated template registry functionality for scoped template management
  • Updates template resolution to check isolated registries first before falling back to global templates
  • Adds comprehensive test coverage for isolated template functionality

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/runtime/src/internal/compute/IsolatedFunctions.ts Updates type imports and function signature to accept undefined functions
packages/runtime/src/internal/Renderer.ts Updates template resolution to pass full runtime context
packages/runtime/src/internal/IsolatedTemplates.ts New file implementing isolated template registry management
packages/runtime/src/internal/CustomTemplates/utils.ts Adds isolated template resolution logic and updates function signature
packages/runtime/src/internal/CustomTemplates/utils.spec.ts Updates test to use new function signature format
packages/runtime/src/internal/CustomTemplates/expandCustomTemplate.ts Adds logic to retrieve templates from isolated registries
packages/runtime/src/index.ts Changes export to named export for customTemplates
packages/runtime/src/createRoot.ts Integrates isolated template registration and cleanup
packages/runtime/src/createRoot.spec.ts Adds test cases for isolated template functionality
packages/runtime/src/StoryboardFunctionRegistry.ts Updates function signature to accept undefined functions
packages/runtime/src/CustomTemplates.ts Refactors CustomTemplateRegistry to support isolated mode

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@codecov
Copy link

codecov bot commented Sep 17, 2025

Codecov Report

❌ Patch coverage is 92.59259% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.20%. Comparing base (9fd61b9) to head (f06f20d).
⚠️ Report is 3 commits behind head on v3.

Files with missing lines Patch % Lines
packages/runtime/src/CustomTemplates.ts 80.00% 0 Missing and 1 partial ⚠️
packages/runtime/src/internal/IsolatedTemplates.ts 90.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##               v3    #4785      +/-   ##
==========================================
- Coverage   95.21%   95.20%   -0.02%     
==========================================
  Files         210      211       +1     
  Lines        9176     9198      +22     
  Branches     1769     1774       +5     
==========================================
+ Hits         8737     8757      +20     
  Misses        324      324              
- Partials      115      117       +2     
Files with missing lines Coverage Δ
packages/runtime/src/StoryboardFunctionRegistry.ts 89.65% <ø> (ø)
packages/runtime/src/createRoot.ts 96.66% <100.00%> (+0.07%) ⬆️
...c/internal/CustomTemplates/expandCustomTemplate.ts 98.11% <100.00%> (ø)
...ages/runtime/src/internal/CustomTemplates/utils.ts 100.00% <100.00%> (ø)
packages/runtime/src/internal/Renderer.ts 93.70% <100.00%> (ø)
.../runtime/src/internal/compute/IsolatedFunctions.ts 100.00% <ø> (ø)
packages/runtime/src/CustomTemplates.ts 97.80% <80.00%> (-1.04%) ⬇️
packages/runtime/src/internal/IsolatedTemplates.ts 90.00% <90.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cypress
Copy link

cypress bot commented Sep 17, 2025

next-core    Run #11669

Run Properties:  status check passed Passed #11669  •  git commit 5378779fc6 ℹ️: Merge f06f20d56216b79e0d128f67e9bb9e80947faf79 into 9fd61b9326dd036ab799828cbe3f...
Project next-core
Branch Review steve/v3-isolated-templates
Run status status check passed Passed #11669
Run duration 00m 26s
Commit git commit 5378779fc6 ℹ️: Merge f06f20d56216b79e0d128f67e9bb9e80947faf79 into 9fd61b9326dd036ab799828cbe3f...
Committer Shenwei Wang
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 17
View all changes introduced in this branch ↗︎

@weareoutman weareoutman merged commit 6b4f62f into v3 Sep 17, 2025
7 of 9 checks passed
@weareoutman weareoutman deleted the steve/v3-isolated-templates branch September 17, 2025 10:20
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (11)
packages/runtime/src/CustomTemplates.ts (2)

21-28: 为新增的隔离构造参数补充文档,澄清实例用途

#isolated 与可选构造参数用于标记“仅在隔离场景使用的注册表”。建议在类与构造器处加入注释,说明:

  • 该实例不会操作 customElements 已定义元素;
  • 与全局 customTemplates 的职责边界;
  • 典型使用方式(例如由 IsolatedTemplates 工厂创建)。

可选补丁(仅注释):

-export class CustomTemplateRegistry {
+// 用途:
+// - 非隔离:作为全局模板注册表,定义并缓存自定义元素的元数据;
+// - 隔离:作为每 root 的临时模板仓库,仅缓存元数据,不触碰 customElements。
+export class CustomTemplateRegistry {
   readonly #registry = new Map<string, CustomTemplate>();
   readonly #isolated: boolean | undefined;

-  constructor(isolated?: boolean) {
+  /** 当 isolated 为 true 时,该实例仅用于隔离 root 的模板缓存。 */
+  constructor(isolated?: boolean) {
     this.#isolated = isolated;
   }

241-245: clearIsolatedRegistry 仅在 isolated=true 生效:建议注明返回值或行为说明

当前方法在非隔离实例上调用无效果,易引发误用。建议:

  • 增加返回布尔值表示是否执行了清理;或
  • 至少补充注释说明在非隔离实例上是 no-op。

可选补丁(保留 API,不改变签名,补注释):

-  clearIsolatedRegistry() {
+  /** 仅当实例为隔离模式时清空内部缓存;非隔离实例调用无任何效果。 */
+  clearIsolatedRegistry() {
     if (this.#isolated) {
       this.#registry.clear();
     }
   }
packages/runtime/src/internal/CustomTemplates/utils.spec.ts (1)

76-81: 测试用例已匹配新签名,建议补一个“无 app.id”分支

当前仅覆盖 ctx.app.id 存在的路径。建议再加一例 ctx.app 未设置时的行为,确保默认解析不回退到意外 tag 名。

packages/runtime/src/createRoot.spec.ts (2)

353-384: 新增“片段作用域下的模板”用例很到位

覆盖了隔离模板的注册、渲染与卸载路径。可考虑断言卸载后再次渲染需重新提供模板,以验证隔离仓库确实被清空。


386-400: “未知模板”用例贴近预期

验证了在未注册模板时渲染为空壳元素的行为。可额外断言无报错日志或 loader 行为(如 unknownBricks 策略)以固定期望。

packages/runtime/src/createRoot.ts (1)

35-38: 引入隔离模板注册入口与 Map 很好,但请补充并发与生命周期说明

建议在 IsolatedTemplates 模块(或此处)记录:

  • 同一 isolatedRoot 多次 render 的合并/覆盖语义;
  • 是否支持 templates: undefined 触发清空;
  • 与函数隔离注册的顺序依赖(此处为“先模板后函数”)。

请确认 registerIsolatedTemplates 的实现对 undefined 入参的语义(清空/忽略/保留)。

packages/runtime/src/internal/CustomTemplates/expandCustomTemplate.ts (1)

56-61: 避免使用多级非空断言链,建议显式校验并抛出更友好的错误

isolatedTemplateRegistryMap.get(... )!.get(tplTagName)! 在竞态或误用下会直接抛 TypeError。建议在缺失时抛出包含 tplTagNameisolatedRoot 的明确错误,便于排障。

可选补丁:

-  const { bricks, proxy, state, contracts } = hostBrick.runtimeContext
-    .isolatedRoot
-    ? isolatedTemplateRegistryMap
-        .get(hostBrick.runtimeContext.isolatedRoot)!
-        .get(tplTagName)!
-    : customTemplates.get(tplTagName)!;
+  let tpl = hostBrick.runtimeContext.isolatedRoot
+    ? isolatedTemplateRegistryMap.get(hostBrick.runtimeContext.isolatedRoot)?.get(tplTagName)
+    : customTemplates.get(tplTagName);
+  if (!tpl) {
+    throw new Error(
+      `Template "${tplTagName}" not found for current ${hostBrick.runtimeContext.isolatedRoot ? "isolated root" : "global"} registry`
+    );
+  }
+  const { bricks, proxy, state, contracts } = tpl;

请确认 getTagNameOfCustomTemplate 的返回只会发生在模板已注册时,二者保持强一致,避免运行时落入上述异常分支。

packages/runtime/src/internal/compute/IsolatedFunctions.ts (1)

12-20: 先注册再写入全局 Map,避免注册失败留下脏条目。
当前先 set 后 register;若 registerStoryboardFunctions 抛错,会在 isolatedFunctionRegistry 中遗留无效项。建议调整顺序。

应用此最小化调整:

   const { storyboardFunctions, registerStoryboardFunctions } =
     StoryboardFunctionRegistryFactory({ isolatedRoot });
-  isolatedFunctionRegistry.set(isolatedRoot, storyboardFunctions);
-  registerStoryboardFunctions(functions);
+  registerStoryboardFunctions(functions);
+  isolatedFunctionRegistry.set(isolatedRoot, storyboardFunctions);
packages/runtime/src/internal/CustomTemplates/utils.ts (1)

63-74: 微调可读性:参数解构,减少链式访问。
不改语义,仅提升易读性。

应用此重构:

-export function getTagNameOfCustomTemplate(
-  brick: string,
-  runtimeContext: Pick<RuntimeContext, "app" | "isolatedRoot">
-): false | string {
-  if (runtimeContext.isolatedRoot) {
-    const registry = isolatedTemplateRegistryMap.get(
-      runtimeContext.isolatedRoot
-    );
+export function getTagNameOfCustomTemplate(
+  brick: string,
+  { app, isolatedRoot }: Pick<RuntimeContext, "app" | "isolatedRoot">
+): false | string {
+  if (isolatedRoot) {
+    const registry = isolatedTemplateRegistryMap.get(isolatedRoot);
     if (registry?.get(brick)) {
       return brick;
     }
     return false;
   }
 
   // When a template is registered by an app, it's namespace maybe missed.
-  if (!brick.includes(".") && brick.startsWith("tpl-") && runtimeContext.app) {
-    const tagName = `${runtimeContext.app.id}.${brick}`;
+  if (!brick.includes(".") && brick.startsWith("tpl-") && app) {
+    const tagName = `${app.id}.${brick}`;
     if (customTemplates.get(tagName)) {
       return tagName;
     }
   }
packages/runtime/src/internal/IsolatedTemplates.ts (2)

9-12: 显式标注返回类型以增强可读性。
加上 : void 更直观,防止将来无意返回值。


9-24: 为 registerIsolatedTemplates 增加可选 reset 参数(默认 true)

当前实现每次都会调用 registry.clearIsolatedRegistry(),会在增量/分批注册场景移除此前已注册模板;保留默认 reset=true 以兼容现状,并增加可选项以支持增量注册。

建议改造(保持默认 reset=true):

-export function registerIsolatedTemplates(
-  isolatedRoot: symbol,
-  templates: CustomTemplate[] | undefined
-) {
+export function registerIsolatedTemplates(
+  isolatedRoot: symbol,
+  templates: CustomTemplate[] | undefined,
+  options?: { reset?: boolean }
+): void {
   let registry = isolatedTemplateRegistryMap.get(isolatedRoot);
   if (!registry) {
     registry = new CustomTemplateRegistry(true);
     isolatedTemplateRegistryMap.set(isolatedRoot, registry);
   }
-  registry.clearIsolatedRegistry();
+  if (options?.reset ?? true) {
+    registry.clearIsolatedRegistry();
+  }
   if (Array.isArray(templates)) {
     for (const tpl of templates) {
       registry.define(tpl.name, tpl);
     }
   }
 }

已验证:卸载时会删除映射(packages/runtime/src/createRoot.ts:280),registerIsolatedTemplates 的调用点为 packages/runtime/src/createRoot.ts:204。

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 9fd61b9 and f06f20d.

📒 Files selected for processing (11)
  • packages/runtime/src/CustomTemplates.ts (2 hunks)
  • packages/runtime/src/StoryboardFunctionRegistry.ts (1 hunks)
  • packages/runtime/src/createRoot.spec.ts (1 hunks)
  • packages/runtime/src/createRoot.ts (3 hunks)
  • packages/runtime/src/index.ts (1 hunks)
  • packages/runtime/src/internal/CustomTemplates/expandCustomTemplate.ts (2 hunks)
  • packages/runtime/src/internal/CustomTemplates/utils.spec.ts (2 hunks)
  • packages/runtime/src/internal/CustomTemplates/utils.ts (2 hunks)
  • packages/runtime/src/internal/IsolatedTemplates.ts (1 hunks)
  • packages/runtime/src/internal/Renderer.ts (1 hunks)
  • packages/runtime/src/internal/compute/IsolatedFunctions.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (20.x)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (11)
packages/runtime/src/internal/Renderer.ts (1)

706-706: 传递 runtimeContext 给 getTagNameOfCustomTemplate 的改动合理

与隔离模板解析一致性良好,调用点处理 string | false 的语义不变,后续扩展空间更大。

请确认 getTagNameOfCustomTemplate 的实现与签名已全量迁移,且无遗留的按 appId 字符串调用。

packages/runtime/src/internal/CustomTemplates/utils.spec.ts (1)

9-9: 仅类型导入 RuntimeContext 的微调 OK

减少运行时代码体积,符合 TS 最佳实践。

packages/runtime/src/createRoot.ts (2)

204-206: 在 fragment 下“先注册模板再注册函数”的顺序合理

与扩展流程一致(模板展开依赖函数时可通过后续求值)。若存在模板代理属性依赖 FN.* 的边界情况,建议补一个用例。

可添加 e2e/spec:模板属性内调用 FN,验证首次渲染与重渲染均正常。


280-281: 卸载时清理模板隔离仓库 👍

已与 isolatedFunctionRegistry.delete 保持对称。若存在并发渲染(同 root 多次 render 进行中)建议在 delete 前确保无悬挂异步任务引用旧模板。

如需稳妥,可在 RendererContext.dispatchOnUnmount() 后追加一次“仓库为空”的断言于测试中。

packages/runtime/src/internal/CustomTemplates/expandCustomTemplate.ts (1)

24-24: 引入 isolatedTemplateRegistryMap 的方向正确

与隔离解析路径打通。见下条关于非空断言的健壮性建议。

packages/runtime/src/StoryboardFunctionRegistry.ts (1)

116-147: 为 registerStoryboardFunctions(undefined) 明确语义并确认 currentApp 复用是否为设计

行为说明(已验证):传入 undefined 只会执行 registeredFunctions.clear(),只有在同时传入 app 时才会更新 currentApp。仓内存在多处调用依赖此行为,需确认这是刻意设计并在签名处记录语义或改为同时重置 currentApp。

调用点(供定位):

  • packages/runtime/src/StoryboardFunctionRegistry.spec.ts:162 — registerStoryboardFunctions(undefined)
  • packages/runtime/src/internal/Router.ts:494 — registerStoryboardFunctions(storyboard.meta?.functions, currentApp)
  • packages/runtime/src/internal/compute/IsolatedFunctions.ts:19 — registerStoryboardFunctions(functions)
  • packages/runtime/src/internal/compute/WidgetFunctions.ts:27 — registerStoryboardFunctions(functions)
  • packages/runtime/src/createRoot.ts:202 — registerStoryboardFunctions(functions, app)

建议(二选其一):

  • 在函数签名处添加 JSDoc,明确传入 undefined 为“仅清空已注册函数,未提供 app 时保留 currentApp”的语义(示例差异如下);或
  • 若意图是清空时同时重置上下文,则在清空时显式将 currentApp 置为 undefined。

建议差异(可直接应用):

   function registerStoryboardFunctions(
-    functions: StoryboardFunction[] | undefined,
+    functions: StoryboardFunction[] | undefined,
     app?: PartialMicroApp
   ): void {
+    /**
+     * 传入 `undefined` 表示“清空已注册函数”。若未提供 `app`,会沿用上一轮的 `currentApp`。
+     * 该行为用于隔离根/片段重渲染时的轻量清空,若希望同时重置上下文请改为显式重置 currentApp。
+     */
     if (app) {
       currentApp = app;
     }
packages/runtime/src/index.ts (1)

4-4: 从通配导出改为具名导出:确认无外部依赖

export { customTemplates } from "./CustomTemplates.js";

自动化扫描在当前执行环境未能访问/搜索到仓库文件,无法验证是否有外部或工作区包依赖 runtime 的其它导出(例如 CustomTemplateRegistry)。在本地仓库根目录运行下列命令核查是否存在消费者依赖被移除的导出:

rg -n --hidden -S "from .*\/runtime" -g '!**/dist/**' -g '!**/build/**' -C2 || true
rg -n --hidden -S "from .*CustomTemplates" -g '!**/dist/**' -g '!**/build/**' -C2 || true
rg -n --hidden -S "CustomTemplateRegistry" -g '!**/dist/**' -g '!**/build/**' -C2 || true
rg -n --hidden -S "from .*@next-core\/runtime" -g '!**/dist/**' -g '!**/build/**' -C2 || true

若发现依赖,恢复需要的 re-export(例如 export * from "./CustomTemplates.js" 或补充显式命名导出)。

packages/runtime/src/internal/compute/IsolatedFunctions.ts (2)

1-5: type-only 导入很好,能减少运行时包体与副作用。
这部分变更 LGTM。


12-20: 已确认:卸载会清理 registry,registerStoryboardFunctions 的新签名已落地

  • 卸载清理:packages/runtime/src/createRoot.ts 的 unmount 分支调用了 isolatedFunctionRegistry.delete(isolatedRoot)(约第278–281行)。
  • 签名与调用:packages/runtime/src/StoryboardFunctionRegistry.ts 中 registerStoryboardFunctions 定义为 (functions: StoryboardFunction[] | undefined, app?: PartialMicroApp);调用点包括 packages/runtime/src/internal/compute/IsolatedFunctions.ts(registerStoryboardFunctions(functions))和 packages/runtime/src/createRoot.ts(registerStoryboardFunctions(functions, app)),与签名兼容。
packages/runtime/src/internal/CustomTemplates/utils.ts (1)

49-62: 在隔离上下文中禁用全局/应用级回退:请确认这是预期。
当前一旦存在 isolatedRoot,仅在每根 registry 中命中才返回,否则直接 false,不会回落到 customTemplates 或 app 命名空间。若注册与解析存在时序竞态(解析早于注册),将导致误判。请确认:

  • createRoot/renderer 生命周期能保证“先注册后解析”;
  • 不需要在隔离模式下提供受控回退(例如仅限 app 内回退)。
packages/runtime/src/internal/IsolatedTemplates.ts (1)

4-7: 按 root 维护独立 CustomTemplateRegistry 的设计合理。
Map<symbol, Registry> 贴合需求,构造时传入 true 启用隔离模式也清晰。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants