ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Cocos Creator 引擎实验性 API 规范全解:从 `_experimental` 发布到废弃回收的完整工程实践

Cocos Creator 引擎实验性 API 规范全解:从 `_experimental` 发布到废弃回收的完整工程实践 Cocos Creator 引擎实验性 API 规范全解从_experimental发布到废弃回收的完整工程实践【免费下载链接】cocos-engineCocos simplifies game creation and distribution with Cocos Creator, a free, open-source, cross-platform game engine. Empowering millions of developers to create high-performance, engaging 2D/3D games and instant web entertainment.项目地址: https://gitcode.com/GitHub_Trending/co/cocos-engine本篇技术指南以 Cocos Creator 引擎仓库中的 实验性 API 规范 为骨架系统讲解实验性 API 的发布、修订与召回删除全生命周期规则并结合仓库内动画系统等真实案例以及配套的 废弃 API 框架 说明「先废弃、后删除」的落地方式。读完本文你将掌握_experimental后缀命名的设计动机、基于版本生命周期的删除节奏计算规则以及如何借助deprecated.ts模块与deprecateModuleExportedName接口平滑回收 API并能在自己的引擎扩展或游戏工程中直接复用这套成熟约定。一、为什么需要「实验性 API」机制在 Cocos Creator 引擎这样的大型开源项目中新功能的落地往往不是一蹴而就的。当开发者希望在功能正式定稿之前就获得用户反馈时如果直接把新 API 以正式名称发布会带来两个问题名称占用一旦 API 占用了稳定的正式名称后续正式版若与实验版差异较大改名与迁移成本极高用户误解用户无法仅凭 API 名称判断其稳定性必须去翻警告日志或文档才能获知风险。为此实验性 API 规范 定义了三条明确的动作准则发布Release、修订Revise与召回Recall。它不要求 API 在实验期保持稳定而是通过命名后缀与版本节奏把「不稳定」这一事实透明地暴露给使用者从而在「快速迭代」与「版本演进有序」之间取得平衡。二、发布实验性 API强制_experimental后缀当你要把一个引擎功能以实验性质发布时例如希望在该功能正式落地之前先收集用户反馈规范给出了两条要求必须REQUIRED让该 API 名称以_experimental结尾可以optional在 API 被使用于运行时附加一条警告级别warn level的信息且该信息至多展示一次。2.1 后缀命名为何是强制项规范中明确给出了该要求合理的两个理由不占用稳定 API 的正式名称实验性 API 有独立命名空间未来稳定版本即使与实验版差异很大也能顺利取用正式名称无需担心历史包袱用户零成本识别风险用户不需要检查任何警告或查看任何文档只要看到_experimental后缀就知道这是一个实验接口从而自行决定是否使用。2.2 运行时警告可选但推荐除了命名规范建议在实验性 API 被调用时输出一条警告级别的运行时信息。仓库中的实现位于 cocos/core/utils/x-deprecated.ts引擎通过messageMap按消息 ID 计数配合logTimes字段限制日志输出次数默认全局输出上限为10次源码第 34 行let defaultLogTimes 10;可通过setDefaultLogTimes()调整。2.3 仓库中的真实案例命名约定在 Cocos Creator 引擎中已被广泛使用以下均可在当前仓库中直接检索到模块实验性 API 示例源码位置动画剪辑isAdditive_experimental、addAuxiliaryCurve_experimental、getAuxiliaryCurve_experimental、renameAuxiliaryCurve_experimental、removeAuxiliaryCurve_experimental等cocos/animation/animation-clip.ts动画图控制器setValue_experimental、getValue_experimental、overrideClips_experimental、getAuxiliaryCurveValue_experimentalcocos/animation/marionette/animation-controller.ts动画图变量类型VariableType.VEC3_experimental、VariableType.QUAT_experimentalcocos/animation/marionette/variable/basic.ts类型导出别名Value_experimentalPrimitiveValue的别名cocos/animation/marionette/runtime-exports.ts其中 animation-controller.ts 还展示了一个有趣的「稳定壳 实验核」模式稳定方法setValue直接委托给setValue_experimental而getValue在拿到对象类型的值时会输出警告提示开发者该变量类型当前仅实验性支持应显式通过this.getValue_experimental()获取。这正体现了实验性 API 在运行时附加警告信息的可选实践。三、修订实验性 API无向后兼容义务实验性 API 在其演进过程中由开发者自行决定如何修订不需要保持向后兼容。这是实验性 API 与稳定 API 最核心的差异——它可以随时改签名、改行为不必为已有使用者负责。但这并不意味着可以悄无声息地改。规范明确要求应该在发布说明release note中注明修改内容有条件下最好在文档中同步说明。这样即使 API 形态变化频繁使用者依然能从发布说明中追踪到演进轨迹。四、召回实验性 API版本生命周期与删除节奏当 API 稳定下来之后无论是否有对应的稳定替代品规范规定了一个强制的回收顺序必须先将被废弃的实验性 API 变成废弃deprecatedAPI然后才能从引擎中彻底删除它。也就是说不允许直接从实验一步跳到删除中间必须经过废弃这一过渡状态给用户留下迁移时间。而废弃环节的工程化实现正是下一节将详细介绍的废弃 API 框架。4.1 生命周期定义规范用生命期[a, b]表示该 API 在版本a发布为实验性在版本b稳定。删除节奏完全由生命期跨度的类型决定具体规则与示例汇总如下生命期跨度删除时机规范给出的示例仅跨越补丁版本patch在下一个次要版本中删除存在于[3.7.0, 3.7.4]可在3.8.0中删除仅跨越次要版本[X.Y.*, X.Z.*]在Z - Y个次要版本之后或下一个主版本中删除存在于[3.7.1, 3.9.0]可在3.11.0或4.0.0中删除跨越了主版本仅可在下一个主版本中删除存在于[3.0.0, 5.6.7]只能在6.0.0中删除对表中次要版本一栏做一点推导便于理解[3.7.1, 3.9.0]意味着生命期跨越了3.7、3.8、3.9三个次要版本段即Z - Y 9 - 7 2因此需要再等待 2 个次要版本3.10、3.11即在3.11.0或更激进地在下一个主版本4.0.0中删除。可以看到跨度的版本量级越大要求的等待期越长。这套规则的直观意义是生命期越长、被使用的用户就越多删除时需要给出的缓冲也就越多。五、回收落地废弃 API 框架详解「先废弃、后删除」中的废弃环节引擎提供了完整的工具链支持其接口与用法定义在 废弃 API 文档 中实现位于 cocos/core/utils/x-deprecated.ts。5.1 三个核心操作函数框架围绕对象属性的废弃操作实现了三个函数markAsWarning在给定对象上为已存在的属性嵌入一个警告removeProperty在给定对象上重新定义被移除的属性该属性在对象上不应存在并嵌入一条错误信息replaceProperty在给定对象上重新定义被移除的属性嵌入警告并转发到新属性若新旧参数不兼容需要通过自定义函数适配该属性在对象上不应存在。函数签名如下摘自 cocos/core/utils/x-deprecated.ts与文档一致interface IRemoveItem { name: string; // 被废弃的属性名 logTimes?: number; // 警告输出次数 suggest?: string; // 附加建议 } interface IMarkItem { name: string; // 被废弃的属性名 logTimes?: number; // 警告输出次数 suggest?: string; // 附加建议 } interface IReplacement { name: string; // 被废弃的属性名 logTimes?: number; // 警告输出次数 suggest?: string; // 附加建议 target?: object; // 被废弃属性的目标对象 targetName?: string; // 被废弃属性目标对象的名称 customFunction?: Function; // 自定义替换属性函数 customSetter?: (v: any) void; // 自定义替换属性的 setter customGetter?: () any; // 自定义替换属性的 getter } export let removeProperty: (owner: object, ownerName: string, properties: IRemoveItem[]) void; export let markAsWarning: (owner: object, ownerName: string, properties: IMarkItem[]) void; export let replaceProperty: (owner: object, ownerName: string, properties: IReplacement[]) void; /** 用于设置全局默认的信息输出次数 */ export function setDefaultLogTimes (times: number): void;从源码实现看x-deprecated.ts引擎通过messageMap为每条消息维护独立的count计数只有在item.logTimes item.count时才真正输出日志这正是「控制警告只出现有限次数」的底层机制setDefaultLogTimes在传入值大于 0 时才会生效源码第 40 行。5.2 使用示例废弃 API 文档 给出了完整示例这里完整保留并稍加注释// 对替换参数不兼容的 API通过合适的自定义函数做适配 replaceProperty(AnimationComponent.prototype, AnimationComponent.prototype, [ { name: removeClip, newName: removeState, customFunction: function (...args: any) { const arg0 args[0] as AnimationClip; return AnimationComponent.prototype.removeState.call(this, arg0.name); } } ]); // 将对象属性重定向到新对象 / 新名称 replaceProperty(vmath, vmath, [ { name: vec2, newName: Vec2, target: math, targetName: math, logTimes: 1 }, { name: EPSILON, target: math, targetName: math, logTimes: 2 } ]); // 完全移除属性并给出建议 removeProperty(vmath, vmath, [ { name: random, suggest: use Math.random. } ]); // 仅标记警告不改变行为 markAsWarning(math, math, [ { name: toRadian } ]);5.3 使用注意事项文档还强调了几条实操要点所有操作目标都是对象若要废弃类的成员函数必须传入target.prototypereplaceProperty若不传newName或newTarget则默认与name或target保持一致若希望精确控制警告次数最好在使用前调用setDefaultLogTimes因为其他模块可能修改过默认次数。5.4 模块化维护约定每个模块一个deprecated.ts为了便于维护规范约定按模块划分每个模块维护一个废弃文件统一命名为deprecated.ts放在对应模块目录下并在该模块的index.ts中通过import ./deprecated引入生效。当前仓库中可找到 25 个符合该约定的deprecated.ts例如cocos/2d/components/deprecated.tscocos/3d/skeletal-animation/deprecated.tscocos/audio/deprecated.tscocos/particle/deprecated.tscocos/physics/framework/deprecated.tscocos/scene-graph/deprecated.tscocos/ui/deprecated.ts以 cocos/3d/skeletal-animation/deprecated.ts 为例可以看到经典的废弃别名写法export { SkeletalAnimation as SkeletalAnimationComponent };并辅以deprecated Since v1.2的 JSDoc 标注。注废弃 API 文档中提到的 cocos/utils目录下的deprecated.ts是声明与实现文件在当前仓库中对应实现位于 cocos/core/utils/x-deprecated.ts。该实现文件自身的 JSDoc 标注为deprecated since v3.6.0属于引擎私有接口这恰好是「废弃 API 也会被废弃」的自我实践。除通用deprecated.ts外引擎还按大版本演进维护了版本化废弃文件如 cocos/2d/framework/deprecated-1.2.0.ts、cocos/2d/framework/deprecated-3.0.0.ts、cocos/scene-graph/deprecated-3.7.0.ts 等分别承载对应版本沉淀的废弃逻辑便于追溯历史。六、废弃模块导出名称deprecateModuleExportedName以上介绍的都是对象属性层面的废弃。自3.6.0起引擎还支持对模块导出的对象或类型本身进行废弃接口为deprecateModuleExportedName其声明与实现位于 cocos/core/utils/x-deprecated.ts。6.1 基本用法deprecateModuleExportedName({ ButtonComponent: { newName: Button, since: 1.2.0, removed: false, }, }); deprecateModuleExportedName({ replaceProperty: { since: 3.6.0, removed: false, }, });每个条目包含三个字段newName新名称、since废弃起始版本、removed是否已移除。注册信息会被记录到内部的topLevelDeprecateList中。6.2 触发警告的场景当项目脚本执行以下任意一种导入/访问操作时将会收到废弃警告import { ButtonComponent } from cc;或者import * as cc from cc; console.log(cc.ButtonComponent);仓库内大量模块已接入该接口例如 cocos/2d/framework/deprecated-1.2.0.ts、cocos/input/deprecated-3.3.0.ts、cocos/core/utils/deprecated-3.6.0.ts 等均以import { deprecateModuleExportedName } from ../../core或../core/utils/x-deprecated的方式接入。七、实验性 API → 废弃 API → 删除一个完整的回收路径把实验性规范与废弃框架串联起来一条完整的 API 生命周期演进路径是这样的发布新功能以xxx_experimental命名发布附带可选的运行时警告迭代在实验期内自由修订不保证向后兼容但需在发布说明中记录稳定API 定型后先通过markAsWarning/replaceProperty/removeProperty或deprecateModuleExportedName将其标记为废弃给予用户迁移窗口删除根据生命期跨度的版本节奏补丁→下一个次要版本次要→Z-Y个次要版本后或下一个主版本主版本→下一个主版本在满足条件的版本中彻底移除。这条路径确保了任何 API 在消失之前用户都能通过后缀、警告日志、废弃标注三条线索获知其状态与替代方案。八、实践建议与自检清单基于规范与仓库现有实践这里整理一份可直接参考的自检清单命名检查新发布的实验性 API 是否全部带_experimental后缀是否占用了稳定 API 的正式名称警告检查是否在实验性 API 被调用时输出了警告级别信息是否控制输出次数借助logTimes或setDefaultLogTimes修订记录每次修订是否在发布说明中注明是否同步更新了文档回收顺序是否先经过「废弃」状态再删除而不是直接从实验跳到删除节奏计算删除前是否按生命期跨度确认了允许删除的版本补丁/次要/主版本三档规则模块隔离废弃逻辑是否放在对应模块的deprecated.ts或deprecated-版本.ts中并在index.ts中import生效类型级废弃若废弃的是模块导出名称是否使用deprecateModuleExportedName并正确填写newName/since/removed这套规范与工具链不仅服务于 Cocos Creator 引擎本身的演进也同样适用于基于该引擎的插件、扩展库乃至个人游戏工程的 API 治理——它是在开源协作中让不稳定的创新不伤害稳定的生态的一份成熟范本。延伸阅读实验性 API 规范中文原文Experimental API specification英文版废弃 API 框架详解废弃特性总览废弃 API 核心实现模块划分约定【免费下载链接】cocos-engineCocos simplifies game creation and distribution with Cocos Creator, a free, open-source, cross-platform game engine. Empowering millions of developers to create high-performance, engaging 2D/3D games and instant web entertainment.项目地址: https://gitcode.com/GitHub_Trending/co/cocos-engine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进