资讯动态

astryx 下个版本 codemod 暂存区机制:transforms/next 目录设计、晋升流程与源码实现解析

发布时间:2026/9/15 20:15:28 来源:尧图企业网站定制
astryx 下个版本 codemod 暂存区机制transforms/next 目录设计、晋升流程与源码实现解析【免费下载链接】astryxAn open source design system thats fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx本篇文章围绕 astryx CLI 的packages/cli/assets/codemods/transforms/next/目录展开深入剖析这套先把破坏性变更的 codemod 暂存在 next待版本确定后再晋升到具体版本文件夹的发布协作机制。你将掌握为什么 codemod 必须跟随目标包版本归档、写作者应该遵循哪些规则、pnpm version-packages触发晋升时脚本内部发生了什么以及注册表与upgrade命令如何消费晋升结果。读完即可直接参与 astryx 的 codemod 贡献或在自己的 monorepo 发布流水线中复刻同一套暂存-晋升模式。背景codemod 为什么要暂存而不是直接落版本文件夹在 astryx 的发布体系中codemod 的存放目录有一个隐含约定承载某个 codemod 的文件夹就是包含该破坏性变更的目标包版本。例如packages/cli/assets/codemods/transforms/v0.0.15/存放的是一系列需要随 v0.0.15 一起发布、用于把用户代码从旧 API 迁移到新 API 的自动化改写脚本。问题在于时间差普通功能 PRfeature PR合并时往往还不知道自己破坏性变更最终会落在哪个版本号上。版本号是由 Changesets 的 Version Packages PR 在changeset version把所有待发布 changeset 结算后统一决定的。如果功能 PR 提前猜一个v0.x.y文件夹很可能猜错导致 codemod 被归档进错误的版本目录。于是transforms/next/这个暂存区应运而生其工作方式与 Changesets 的 staging 思想一致贡献者在next/下暂存新 codemod发布/版本结算versioning阶段再把它**晋升promote**到真正的版本文件夹晋升由pnpm version-packages在changeset version之后自动完成。当前仓库中next/目录的实际内容next/README.md 与index.mjs就是这一机制的入口正常情况下它只保留 README 和一个导出空数组的占位 manifest任何实质 codemod 都在被晋升后清空。写作者规则如何向 next 暂存区提交 codemod原文档明确了四条贡献者必须遵守的 Authoring rules结合源码可以展开如下直接在next/目录下新增 transform 模块模块本身是一个.mjs文件默认导出一个形如(file, api) string | null | undefined的 transform 函数并导出一个meta对象title/description/fileExtensions等。类型契约定义在 packages/cli/authoring/codemod/type.ts 中AstryxCodemodFile提供path与sourceCodemodTransform返回新源码则覆盖文件返回null/undefined则保持不变。更新本目录的index.mjs按执行顺序导出这些 transformindex.mjs是版本文件夹的清单manifest格式为若干import语句加一个export default [...]数组每个元素形如{ name, transform, meta }并可用optional: true标记可选 codemod见下文 v0.0.15 示例。顺序即执行顺序因此要按迁移的依赖关系排列。测试紧邻 transform 放置遵循已有版本文件夹的模式即放在next/__tests__/下晋升后随之迁入版本文件夹的__tests__/使用 vitest 编写通过 jscodeshift 的withParser(tsx)构造真实 AST 环境做断言。不要在 feature PR 里猜测未来的v0.x.y文件夹不要把发布专属内容写进这个 README——它始终属于next晋升时会被脚本显式排除不会复制进版本文件夹。晋升Release promotion一次命令完成的自动化迁移原文档指出pnpm version-packages会在changeset version之后运行scripts/promote-codemod-next.mjs。查根目录 package.json 可确认这条脚本链的真实定义version-packages: changeset version node scripts/promote-codemod-next.mjs node scripts/sync-internal-deps.mjs node scripts/format-changelogs.mjs晋升脚本的行为按原文档概括为三点把next/目录下除 README 外的每一个条目复制进packages/cli/assets/codemods/transforms/vnew-core-version/从next/移除已晋升的文件晋升完成后Version Packages PR 应审查生成的版本文件夹如果是全新版本文件夹则把它登记进packages/cli/assets/codemods/registry.mjs。值得注意脚本本身已经自动完成了 registry 注册见ensureRegistryEntry因此第 3 点实际是要求 PR 审查确认 registry 变更是否符合预期而不是人工手改。源码级解析promote-codemod-next.mjs 的内部流程scripts/promote-codemod-next.mjs 是整套机制的核心实现导出promoteCodemodNext({ root })函数关键步骤依次如下。1. 枚举可晋升条目并识别空暂存listPromotableEntries读取next/下的条目过滤掉 README 和以.开头的隐藏文件。isEmptyStage则处理一个隐蔽的边界每次发布后脚本都会用导出空数组的占位 manifest重新播种next/因此什么都没暂存不等于目录为空而是只有一个导出[]的 index.mjs。若不加区分一次没有 codemod 的发布会把占位清单晋升进版本文件夹并注册一个不含任何 transform 的版本层级——测试does nothing when next/ holds only the re-seeded empty manifest专门守护了这一点。2. 读取并校验目标版本号目标版本取自packages/core/package.json的version字段此时changeset version已把它更新为本次即将发布的真实版本并用正则^\d\.\d\.\d(?:-[0-9A-Za-z.-])?$校验语义化版本格式。随后强制要求next/必须包含index.mjs否则抛错——因为晋升后的版本文件夹必须能被注册表动态加载。3. 晋升与合并策略三种分支目标版本文件夹可能已存在例如本发布周期早些时候有 codemod PR 直接播种了vX.Y.Z/后来又有人往next/追加了新 codemod。此时晋升不是简单覆盖而是合并index.mjsmergeIndexManifests解析两份清单保留现有目标的 import 与条目在前、新暂存条目在后并按 transform 的name去重——同名条目直接跳过避免重复注册__tests__等目录mergeDirInto递归合并目录内容遇到同名文件视为真实冲突并抛错普通文件直接移动若目标已存在同名文件同样抛错拒绝覆盖refusing to overwrite existing ...。这种同名即冲突、绝不静默覆盖的保守策略保证了晋升可重跑、可审查。4. 重新播种 next 并注册 registry晋升完成后脚本向next/index.mjs写回标准占位清单含版权头与export default [];让暂存区在下个发布周期保持可用。随后ensureRegistryEntry在registry.mjs的 Map 终止符]);前插入形如[0.4.0, () import(./transforms/v0.4.0/index.mjs)],的惰性加载条目若该版本已存在则跳过。最后用 Prettier 对改动文件统一格式化并返回{ version, promoted, registryUpdated, mergedIntoExisting }供 CLI 打印晋升摘要。对应的 scripts/promote-codemod-next.test.mjs 覆盖了主要行为仅 README 时无操作、仅占位 manifest 时无操作且不创建版本文件夹、正常晋升并注册、版本文件夹已存在时合并、同名冲突抛错、注册表自动更新等。晋升后的消费端注册表与 upgrade 命令晋升产生的版本文件夹最终由 packages/cli/assets/codemods/registry.mjs 统一索引。该文件维护一个Map把每个已发布版本映射到其 manifest 的惰性 import并对外导出versions所有已注册版本号按semverCompare升序排列latestVersion最新版本getTransformsBetween(from, to)返回(from, to]区间内各版本{ version, transforms }的有序数组transforms即各版本index.mjs默认导出的{ name, transform, meta }列表。这套 API 正是 upgrade 命令的选型引擎在 packages/cli/api/upgrade/_adapter.mjs 中可以看到它导入getTransformsBetween与latestVersion检测用户已安装的 core 版本后据此选择需要执行的 codemod 集合再交给 codemod runner确保 jscodeshift 可用、逐文件执行 transform完成升级。也就是说next/暂存 → 版本结算 → 晋升归档 → registry 注册 → upgrade 按版本区间执行构成了 astryx 自动化升级能力的完整闭环。实战参照v0.0.15 版本文件夹的样子以已晋升的 transforms/v0.0.15/index.mjs 为例可以看到清单的标准形态每个 codemod 一个条目name为小写连字符命名transform与meta分别从同目录.mjs导入optional: true标记可跳过项如migrate-theme-selectors-to-data-attrs其余为默认必跑项。v0.0.15 共包含 7 个 transform覆盖日期选择器改名、isStreaming→isStopShown、命令式 ref →handleRef、Stack 的element→as以及若干 children/theme selector 迁移。单个 transform 的实现可以看 rename-stack-element-to-as.mjs它通过api.jscodeshift解析 JSX遍历JSXOpeningElement仅当组件名命中XDSStack / XDSHStack / XDSVStack / XDSStackItem集合时才把element属性改名为as有改动则返回root.toSource({ quote: single })否则返回undefined保持文件不变。其配套测试tests/rename-stack-element-to-as.test.mjs 用 vitest 验证了四个目标组件各自改名、单文件多组件、无关组件如XDSButton不受影响、无改动时返回undefined等行为其中不触碰无关组件的用例体现了 codemod 必须保守克制的原则。另一个值得借鉴的实现是 migrate-theme-selectors-to-data-attrs.mjs它用正则把.xds-button.primary.sm:hover这类裸类选择器改写为.xds-button[data-variantprimary][data-sizesm]:hover并通过组件维度的白名单颜色、状态、尺寸、文本类型、方向等枚举集合严格控制改写范围——未知组件与有歧义的值一律原样保留fileExtensions覆盖.css/.scss/.ts/.tsx等常见源码与样式文件。贡献者实操清单如果你要为 astryx 提交一个新的破坏性变更 codemod流程总结如下在packages/cli/assets/codemods/transforms/next/下新增your-codemod.mjs按 type.ts 的契约导出meta与默认 transform 函数在next/index.mjs中按执行顺序追加{ name, transform, meta }可选 codemod 加optional: true并在next/__tests__/下仿照版本文件夹测试模式补测试不要在 feature PR 中创建任何v0.x.y文件夹——版本号交给 Version Packages PR 结算合入后由发布流程的pnpm version-packages自动完成晋升、合并、registry 注册与next/重新播种你只需在 Version Packages PR 中复核生成的版本文件夹与 registry 变更。小结transforms/next/本质上是一套延迟绑定版本号的发布协作协议把写 codemod与定版本两个时间点解耦让普通 feature PR 无需预知版本号同时保证 codemod 一定归档在正确的目标版本下。从写作者规则、晋升脚本的合并语义、注册表的版本区间查询到 upgrade 命令的消费链路这套机制在 astryx 仓库中形成了完整、可测试、可审计的自动化闭环也为其 CLI 的平滑升级体验提供了底层保障。【免费下载链接】astryxAn open source design system thats fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价