返回全部 Skills

migrate-radix-to-base

开发工具

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

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项目的基础库时使用。处理单个组件(如“迁移手风琴组件”)和整个项目。

Radix UI -> Base UI 迁移

你将 shadcn 包装器、手写 Radix 组合及其消费者迁移到 @base-ui/react,确保每一步项目都可构建。请精确;切勿猜测映射关系。当某个属性或部分不在这些参考文件中时,在转换前检查 node_modules/@base-ui/react/**/*.d.ts,并将差距记录在报告中。

前置检查(始终执行)

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

策略:首先使用金对,其次使用转换引擎

  • 通过 CLI 使用金对(首选)。 如果项目是 shadcn 且具有已知样式(radix-<style>),则 shadcn CLI 本身是金对执行器:
  1. 首先对每个 ui 包装器进行分类:将用户文件与其原始来源进行比较,使用 components.json 中的样式逐字地放在 URL 中(https://ui.shadcn.com/r/styles/<style>/<component>.jsonfiles[0].content)。这适用于带前缀的样式(radix-nova)和旧版无前缀样式(new-york、new-york-v4、default),它们仍然可用。
  2. 全项目模式:立即将 components.json 中的样式 radix-<style> 翻转为 base-<style>。渐进模式:暂时不要翻转(项目仍然是 radix 占多数;翻转只在最后一个组件之后进行);直接通过 URL 获取 base 变体(https://ui.shadcn.com/r/styles/base-<style>/<component>.json)。
  3. 原始包装器,全项目模式:shadcn add <component> --overwrite 提供具有项目精确图标/字体/预设解析的 base 变体。切勿批量 --all --overwrite;逐个组件进行,否则你会陷入无关的注册表版本漂移。渐进模式:永远不要使用 --overwrite(它会破坏消费者仍在导入的原始文件);将获取的 base 变体内容写入 <component>-base.tsx
  4. 自定义包装器:获取 base 变体并将用户的差异重播到其上(他们的自定义必须保留;--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 对应项(没有 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 FORWARD 规则;部分重命名)、每个系列属性表(overlays.mdmenus.mdform-controls.mddisclosure.mddisplay-misc.md)、class-mapping.md 用于 data-attribute/CSS-var 重写,以及 wrapper-shapes.md 用于精确的目标形状(tooltip arrow、SubContent 默认值、select 解剖)进行转换。

模式

渐进模式(默认)。 “迁移 accordion” = 单个组件,strangler-fig 模式:

  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 包装器。
  • 行为差异被标记,绝不静默修补(tabs 手动激活、menu 项目点击不关闭、nav-menu 50ms 延迟)。目标是符合 shadcn base 注册表惯用风格的 Base UI。
  • 诚实报告:跳过/回退的文件被标记为已标记,绝不会被列为已迁移。先前存在的失败被命名为先前存在。

验证和报告

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

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

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

每个 .migration/<component>.md 使用完全相同的结构(这是公开文档;报告必须匹配它):

# <component>

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

## 已更改

<每个被触及的文件,包含什么更改以及原因;对任何值得注意的内容包括文件:行。确认遗留扫描是干净的:对组件的文件执行 grep -n "radix-ui\|@radix-ui">

## 未更改

<看起来相关但有意未被触及的文件,附上原因(cmdk/vaul/sonner 不是 radix;无关的漂移等)>

## 行为变化

<编译正常但行为不同的差异;已标记,绝不修补(tabs 激活、菜单点击关闭、延迟等)。如无则留空>

## 手动验证

<该基础组件系列的简短手动 QA 检查清单:对话框的焦点返回、菜单/选择键盘导航 + 首字母输入、tooltip 延迟感觉、slider 提交事件。具体步骤,大约一分钟的点击操作>