在日常开发中,我们经常会写一些定制化组件。但如果想要在多个项目中复用,并且像使用 Shadcn/ui 官方组件一样通过 CLI shadcn add
快速引入,该如何实现呢?本文将带你从零搭建属于自己的 Shadcn/ui Registry。
为什么要做自定义 Registry?
- 复用:一次开发,多次复用,不用再手动复制组件文件。
- 一致性:团队共享组件,保持风格统一。
- CLI 集成:通过
npx shadcn add
一键安装,享受官方组件一样的体验。 - 可扩展:支持依赖声明、CSS 追加、多文件修改,甚至私有化部署。
一、搭建组件 Registry 仓库
新建一个仓库,例如 acme-ui-registry
,结构如下:
acme-ui-registry/
├─ components/
│ └─ ui/
│ └─ smart-button.tsx
├─ lib/
│ └─ utils.ts
├─ styles/
│ └─ tokens.css
├─ smart-button.json ← 组件清单
└─ registry.json ← Registry 索引
1. Registry 索引文件
在根目录创建 registry.json
:
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "@acme",
"items": ["smart-button"]
}
2. 单个组件定义文件
创建 smart-button.json
:
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "smart-button",
"type": "registry:component",
"dependencies": ["react", "clsx"],
"registryDependencies": ["@shadcn/button"],
"files": [
{ "path": "components/ui/smart-button.tsx", "target": "components/ui/smart-button.tsx" },
{ "path": "lib/utils.ts", "target": "lib/utils.ts" },
{ "path": "styles/tokens.css", "target": "app/globals.css", "append": true }
]
}
二、发布 Registry
公共部署
把仓库托管在 GitHub Pages、Vercel 或 S3。CLI 会根据 URL 获取:
- 索引地址:
https://your-domain.com/registry.json
- 组件地址:
https://your-domain.com/smart-button.json
私有部署
需要鉴权时,可在消费项目的 components.json
中配置 headers:
{
"registries": {
"@acme": {
"url": "https://registry.company.com/{name}.json",
"headers": { "Authorization": "Bearer ${REGISTRY_TOKEN}" }
}
}
}
三、在项目中使用
初始化
在目标项目中先初始化一次:
npx shadcn@latest init
配置自定义 Registry
在 components.json
里添加:
{
"aliases": { "components": "@/components", "utils": "@/lib/utils" },
"registries": {
"@acme": "https://your-domain.com/{name}.json"
}
}
安装自定义组件
npx shadcn@latest add @acme/smart-button
也可以直接指定 URL:
npx shadcn add https://your-domain.com/smart-button.json
四、示例组件
components/ui/smart-button.tsx
import * as React from "react";
import { cn } from "@/lib/utils";
type SmartButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
loading?: boolean;
};
export function SmartButton({ className, loading, children, ...props }: SmartButtonProps) {
return (
<button
className={cn(
"inline-flex items-center justify-center h-9 rounded-md px-4 text-sm font-medium",
"bg-primary text-primary-foreground hover:opacity-90 disabled:opacity-50",
className
)}
disabled={loading || props.disabled}
{...props}
>
{loading ? "Loading..." : children}
</button>
);
}
现在,你就可以在任意项目中直接通过 CLI 引入它了。
五、注意事项
path
与target
要和components.json.aliases
对应,否则路径解析会失败。- 可以通过
append: true
在用户的 CSS 或配置文件中自动追加内容。 dependencies
管理 npm 包依赖,registryDependencies
管理其他 Registry 组件依赖。- 支持多注册表命名空间,适合团队拆分使用。
总结
通过搭建自己的 Shadcn/ui Registry,我们就能让自定义组件享受与官方组件同样的 CLI 体验:
shadcn add @acme/xxx
即可一键引入。- 团队共享组件,避免重复造轮子。
- 支持公共和私有场景,灵活可扩展。
赶快把你常用的组件整理成一个私有 Registry,提升开发效率吧 🚀
Comments NOTHING