返回全部 Skills

migrate-radix-to-base

开发工具

将React项目和组件从Radix UI迁移到Base UI。在要求从radix迁移、转为base-ui、转换radix原语或切换shadcn项目的基础库时使用。处理单个组件(如“migrate accordion”)和整个项目。

2

下载量

AI SkillHub 能力展示图

安装方式

命令行安装

在项目根目录执行以下命令,完成 Skill 安装。

npx bzskills add shadcn/ui --skill migrate-radix-to-base

skill.md

name: migrate-radix-to-base
description: 将React项目和组件从Radix UI迁移到Base UI。在要求从radix迁移、转为base-ui、转换radix原语或切换shadcn项目的基础库时使用。处理单个组件(如“migrate accordion”)和整个项目。

Radix UI 到 Base UI 迁移

你将 shadcn 封装器、手动编写的 Radix 组合以及它们的消费者迁移到 @base-ui/react,并确保项目在每个步骤中都能成功构建。请保持精确;切勿猜测映射关系。当某个属性或部件不在这些参考文件中时,请先检查 node_modules/@base-ui/react/**/*.d.ts,然后再进行转换,并在报告中记录差距。

预处理(始终执行)

  1. 运行 npx shadcn@latest info --json(或项目的 runner):获取当前基础、样式(例如 radix-lyra)、tailwind 版本、别名、已安装组件和包管理器。信任它胜过推断。
  2. 检测包管理器(packageManager 字段 / lockfile:pnpm-lock.yaml、bun.lock、yarn.lock、package-lock.json),并在每次安装时使用它。切勿留下旧的 lockfile。
  3. 要求干净的 git 树;在分支上工作;每个组件一个提交。
  4. 在接触依赖之前进行基线检查:运行项目的类型检查/构建,以便已有的失败不会归咎于你。
  5. @base-ui/react 与 Radix 一起安装。Radix 包仅在最后一个组件迁移完成后才移除(两者可以共存)。

策略:先黄金配对,后转换引擎

  • 通过 CLI 进行黄金配对(首选)。 如果项目是 shadcn 且具有已知样式(radix-<style>),则 shadcn CLI 本身是黄金配对的执行者:
  1. 首先对每个 UI 封装器进行分类:将用户文件与其原始标准来源进行差异比较,在 URL 中逐字使用 components.json 的样式(https://ui.shadcn.com/r/styles/<style>/<component>.json,files[0].content)。这适用于带前缀的样式(radix-nova)和旧版无前缀的样式(new-york、new-york-v4、default),这些样式仍然可用。
  2. 全项目模式:立即将 components.json 中的样式从 radix-<style> 翻转为 base-<style>渐进模式:暂时不要翻转(项目仍以 radix 为主;翻转仅在最后一个组件之后进行一次);通过 URL 直接获取基础变体(https://ui.shadcn.com/r/styles/base-<style>/<component>.json)。
  3. 原样封装器,全项目模式shadcn add <component> --overwrite 提供具有项目精确图标/字体/预设解析的基础变体。切勿批量使用 --all --overwrite;逐个组件进行,否则你会淹没在无关的注册表版本漂移中。渐进模式:切勿使用 --overwrite(它会破坏消费者仍在导入的原始文件);而是将获取的基础变体内容写入 <component>-base.tsx
  4. 自定义封装器:获取基础变体,并将用户的差异重放到其上(他们的自定义必须保留;--overwrite 会破坏它们)。可大规模工作的机械实现:git merge-file user.tsx radix-golden.tsx base-golden.tsx(三路合并,以 radix 黄金版本为祖先)会自动解析大多数文件;使用参考表手动解决冲突。
  5. 对每个黄金配对文件强制进行遗留扫描,包括那些合并“干净”的文件:在每个文件中执行 grep -n "radix-ui\|@radix-ui\|IconPlaceholder"。注册表有时会在变体之间重新排序函数,这会导致三路合并报告零冲突,但留下陈旧的 radix 片段。干净的合并并不证明文件是干净的。

这比重构转换更可靠;只要配对存在,就使用它。消费者/应用代码没有 CLI 机制:始终根据 consumer-props.md 手动迁移。

  • 旧版样式(new-york、new-york-v4、default):仅分类,不重放。 这些没有基础对应的版本(没有 base-new-york),将其重新定位到 base-<style> 变体会重新设计用户应用的样式。仅使用 radix 黄金版本来检测自定义,然后对用户自己的文件运行转换引擎:重写基本组件,保留其确切类,应用类映射重命名。他们的外观保持不变。在旧版全项目迁移结束时,标记(不要修复):样式名称对 CLI 来说仍然显示为 radix,因此未来的 shadcn add 将提供 radix 变体;由用户决定是否切换样式或手动添加。
  • 转换引擎(备选)。 手动编写的 Radix 代码、非 shadcn 项目、未知样式:使用以下内容进行转换:universal-patterns.md(两种形式的导入:radix-ui@radix-ui/react-*;asChild -> render 及工作示例;Portal>Positioner>Popup;positioner 转发规则;部件重命名)、每个系列的属性表(overlays.mdmenus.mdform-controls.mddisclosure.mddisplay-misc.md)、用于数据属性/CSS 变量重写的 class-mapping.md,以及用于精确目标形状(工具提示箭头、SubContent 默认值、选择结构)的 wrapper-shapes.md

模式

渐进式(默认)。 “迁移 accordion” = 一个组件,绞杀者模式:

  1. 首先检测进行中状态:是否存在 <component>-base.tsx,消费者在旧/新导入之间分割。文件即状态;继续,切勿重新开始。
  2. 如果该组件导入了仍在使用 radix 的其他 UI 封装器(select -> button),则停止并建议首先自底向上迁移这些封装器。
  3. 将迁移版本写入 <component>-base.tsx(原始文件不变;黄金配对内容通过 URL 获取,或根据上述策略手动转换);进行类型检查。逐个重新指向消费者(导入 + consumer-props.md 中的调用点属性);逐个进行类型检查。当没有消费者导入原始文件时:删除它,将 -base 重命名为原始文件名,重新翻转导入,最终检查,提交。当项目中最后一个 radix 封装器完成后,将 components.json 翻转为 base-<style> 并移除 radix 依赖。

全项目模式(仅在明确要求时):按依赖顺序对每个组件执行相同的工作(首先处理叶子/共享封装器,如 button 和 label)。完成封装器后,根据 consumer-props.md 扫描所有应用代码——调用点的破坏面比 asChild 大得多。然后移除 radix 依赖,安装,完整构建。

硬性规则

  • 切勿接触非 radix 库或其封装器:cmdk (command)、vaul (drawer)、sonner、input-otp、react-day-picker (calendar)、recharts (chart)。将它们报告为有意未触及。
  • 没有 Base UI 对应项:AspectRatio -> CSS aspect-ratio div;Label -> 原生 <label>;VisuallyHidden -> sr-only;Direction -> Direction Provider(direction 属性,不是 dir)。Popover Anchor 和 NavigationMenu Indicator 没有等效项:惰性传递 + 标志。
  • button.tsx 迁移到真正的 @base-ui/react/button 基本组件,绝不是手动编写的 useRender 封装器。
  • 行为差异会被标记,而不会静默修补(标签页手动激活、菜单项点击不关闭、导航菜单 50ms 延迟)。目标是符合 shadcn 基础注册表习惯风格的 Base UI。
  • 诚实报告:跳过/回退的文件被标记为已标记,绝不作为已迁移。已有故障被命名为已有故障。

验证和报告

每个文件进行类型检查,每批进行构建,最后进行完整构建与基线比较。

报告保存在项目根目录下的 .migration/ 目录中,每个组件一个文件:.migration/<component>.md(例如 .migration/accordion.md)。规则:

  • 每次运行会为它迁移的每个组件写入(或完全覆盖)文件。重新运行组件会替换其报告;切勿触碰其他组件的文件。
  • 多组件运行(“迁移 alert-dialog 和 dropdown-menu”)会为每个组件写入一个自包含的文件;共享的消费者扫描说明会在每个受影响的文件中重复。
  • 全项目模式会写入每个组件的文件,外加 .migration/project.md(依赖交换、应用代码扫描摘要、最终构建结果)。
  • 没有索引文件。迁移状态从磁盘推导,而非维护:当被问及“还剩什么”时,扫描项目的 ui 目录(来自 shadcn info 的 ui 别名,例如 components/ui 或 src/components/ui)以查找剩余的 radix 导入。每次运行的摘要末尾提供该推导计数(“N 个封装器仍在使用 Radix”)。

每个 .migration/<component>.md 使用完全此结构(它是公开记录的;报告必须匹配它):

# <component>

<日期,使用的策略(通过 CLI 的黄金配对 / 合并 / 引擎),一句话结论>

## 已更改

<每个被触碰的文件,以及更改内容和原因;对任何重要内容包含 file:line。确认遗留扫描是干净的:在此组件的文件上执行 `grep -n "radix-ui\|@radix-ui"`>

## 未处理

<看似相关但故意未触碰的文件,附上原因(cmdk/vaul/sonner 不是 radix;无关漂移等)>

## 行为变化

<编译正常但行为不同的差异;已标记,绝不修补(标签页激活、菜单点击关闭、延迟……)。如果没有,则此项为空>

## 手动验证

<此基元系列的简短手动 QA 检查清单:对话框上的焦点返回、菜单/选择上的键盘导航 + 类型搜索、工具提示延迟感受、滑块提交事件。具体步骤,一分钟点击>