[{"data":1,"prerenderedAt":426},["ShallowReactive",2],{"content:\u002Fposts\u002F2026\u002Fpublish-your-own-shadcn-extension-with-cli":3,"surround:\u002Fposts\u002F2026\u002Fpublish-your-own-shadcn-extension-with-cli":415},{"id":4,"title":5,"body":6,"canonical":392,"categories":393,"date":395,"description":396,"draft":397,"extension":398,"image":399,"meta":400,"navigation":401,"path":402,"permalink":392,"readingTime":403,"recommend":392,"references":392,"seo":408,"sitemap":409,"stem":410,"tags":411,"type":392,"updated":413,"__hash__":414},"content\u002Fposts\u002F2026\u002Fpublish-your-own-shadcn-extension-with-cli.md","发布自己的 shadcn-vue 扩展组件，并支持 CLI 安装",{"type":7,"value":8,"toc":373},"minimark",[9,13,21,43,64,71,77,87,90,129,133,136,172,175,179,182,190,197,203,206,212,222,230,236,242,257,260,263,269,272,278,285,288,294,297,303,306,309,313,328,332,341,345,353,356,365,368],[10,11,12],"p",{},"shadcn-vue 支持自定义 Registry。我们可以把自己的组件、组合式函数或其他文件构建成 Registry Item，再通过 CLI 安装到其他项目中，使用体验与安装官方组件基本一致。",[10,14,15,16,20],{},"它可以让 CLI 下载组件源码及相关依赖，并写入使用者的项目。下面以发布一个名为 ",[17,18,19],"code",{"code":19},"copy"," 的组件为例，走完配置、构建、发布和安装的完整流程。",[22,23,24],"note",{},[10,25,26,27,30,31,38,39,42],{},"本文介绍的是 Vue 版的 ",[17,28,29],{"code":29},"shadcn-vue","，所有 Schema 和命令均以 ",[32,33,37],"a",{"href":34,"rel":35},"https:\u002F\u002Fwww.shadcn-vue.com\u002F",[36],"nofollow","shadcn-vue 官方文档"," 为准，不要与 React 版的 ",[17,40,41],{"code":41},"shadcn"," CLI 混用。",[44,45,46],"blockquote",{},[10,47,48,49,54,55,63],{},"完整字段说明可以查看 shadcn-vue 官方的 ",[32,50,53],{"href":51,"rel":52},"https:\u002F\u002Fwww.shadcn-vue.com\u002Fdocs\u002Fregistry",[36],"Registry 文档"," 和 ",[32,56,59,62],{"href":57,"rel":58},"https:\u002F\u002Fwww.shadcn-vue.com\u002Fdocs\u002Fregistry\u002Fregistry-json",[36],[17,60,61],{"code":61},"registry.json"," Schema","。目前 Registry 仍属于实验性功能，升级 CLI 后建议重新构建并验证一次。",[65,66,68,69],"h2",{"id":67},"创建-registryjson","创建 ",[17,70,61],{"code":61},[10,72,73,74,76],{},"在项目根目录创建 ",[17,75,61],{"code":61},"：",[78,79,85],"pre",{"className":80,"code":82,"filename":61,"language":83,"meta":84},[81],"language-json","{\n  \"$schema\": \"https:\u002F\u002Fshadcn-vue.com\u002Fschema\u002Fregistry.json\",\n  \"name\": \"prop-show-kit\",\n  \"homepage\": \"https:\u002F\u002Fkit.prop.show\",\n  \"items\": [\n    {\n      \"name\": \"copy\",\n      \"type\": \"registry:component\",\n      \"title\": \"Copy\",\n      \"description\": \"A copy component with tooltip feedback.\",\n      \"dependencies\": [\n        \"@vueuse\u002Fcore\"\n      ],\n      \"registryDependencies\": [\n        \"button\",\n        \"tooltip\"\n      ],\n      \"files\": [\n        {\n          \"path\": \"app\u002Fcomponents\u002Fprop-ui\u002Fcopy\u002FCopy.vue\",\n          \"type\": \"registry:component\"\n        },\n        {\n          \"path\": \"app\u002Fcomponents\u002Fprop-ui\u002Fcopy\u002Findex.ts\",\n          \"type\": \"registry:component\"\n        }\n      ]\n    }\n  ]\n}\n","json","",[17,86,82],{"__ignoreMap":84},[10,88,89],{},"这里有几个容易混淆的字段：",[91,92,93,100,106,123],"ul",{},[94,95,96,99],"li",{},[17,97,98],{"code":98},"name"," 是 Registry 的名称，主要用于元数据，不会决定生成文件的目录或访问地址。",[94,101,102,105],{},[17,103,104],{"code":104},"homepage"," 是 Registry 的主页地址，同样不会自动配置路由。最终的访问地址由构建输出目录和部署平台决定。",[94,107,108,111,112,114,115,118,119,122],{},[17,109,110],{"code":110},"items"," 用来声明所有可安装项。示例中的 ",[17,113,19],{"code":19}," 是一个简单组件，因此使用 ",[17,116,117],{"code":117},"registry:component","；包含页面或多个模块的复杂组件可以使用 ",[17,120,121],{"code":121},"registry:block","。",[94,124,125,128],{},[17,126,127],{"code":127},"files[].path"," 是源文件相对于项目根目录的路径。构建时找不到对应文件会直接失败。",[130,131,132],"h3",{"id":132},"声明依赖",[10,134,135],{},"组件依赖分为两类：",[91,137,138,155],{},[94,139,140,143,144,147,148,151,152,122],{},[17,141,142],{"code":142},"dependencies","：npm 依赖，例如 ",[17,145,146],{"code":146},"@vueuse\u002Fcore","。需要限制版本时，使用 ",[17,149,150],{"code":150},"包名@版本"," 的格式，例如 ",[17,153,154],{"code":154},"@vueuse\u002Fcore@^14.0.0",[94,156,157,160,161,164,165,168,169,122],{},[17,158,159],{"code":159},"registryDependencies","：其他 Registry Item。shadcn-vue 官方组件可以直接写名称，例如 ",[17,162,163],{"code":163},"button","、",[17,166,167],{"code":167},"tooltip","；其他自定义 Registry 中的组件需要填写完整地址，例如 ",[17,170,171],{"code":171},"https:\u002F\u002Fexample.com\u002Fr\u002Feditor.json",[10,173,174],{},"依赖要声明完整，否则使用者虽然能拿到组件源码，安装后仍可能遇到缺少包或导入文件不存在的问题。",[65,176,178],{"id":177},"构建-registry","构建 Registry",[10,180,181],{},"先把 shadcn-vue CLI 安装为开发依赖：",[78,183,188],{"className":184,"code":186,"language":187,"meta":84},[185],"language-bash","pnpm add -D shadcn-vue@latest\n","bash",[17,189,186],{"__ignoreMap":84},[10,191,192,193,196],{},"然后在 ",[17,194,195],{"code":195},"package.json"," 中添加构建脚本：",[78,198,201],{"className":199,"code":200,"filename":195,"language":83,"meta":84},[81],"{\n  \"scripts\": {\n    \"registry:build\": \"shadcn-vue build\"\n  }\n}\n",[17,202,200],{"__ignoreMap":84},[10,204,205],{},"运行脚本：",[78,207,210],{"className":208,"code":209,"language":187,"meta":84},[185],"pnpm registry:build\n",[17,211,209],{"__ignoreMap":84},[10,213,214,215,217,218,221],{},"CLI 默认读取项目根目录下的 ",[17,216,61],{"code":61},"，并把每个 Registry Item 构建到 ",[17,219,220],{"code":220},"public\u002Fr","。上面的配置会生成：",[78,223,228],{"className":224,"code":226,"language":227,"meta":84},[225],"language-text","public\u002Fr\u002Fcopy.json\n","text",[17,229,226],{"__ignoreMap":84},[10,231,232,233,76],{},"如果需要修改输出目录，可以使用 ",[17,234,235],{"code":235},"--output",[78,237,240],{"className":238,"code":239,"language":187,"meta":84},[185],"pnpm exec shadcn-vue build --output .\u002Fpublic\u002Fregistry\n",[17,241,239],{"__ignoreMap":84},[22,243,244],{},[10,245,246,248,249,252,253,256],{},[17,247,61],{"code":61}," 是构建配置，真正提供给 CLI 安装的是构建后的单项 JSON，例如 ",[17,250,251],{"code":251},"copy.json","。不要把 ",[17,254,255],{"code":255},"https:\u002F\u002Fkit.prop.show\u002Fr\u002Fregistry.json"," 当成组件安装地址。",[65,258,259],{"id":259},"本地验证",[10,261,262],{},"启动项目后，先确认浏览器可以访问：",[78,264,267],{"className":265,"code":266,"language":227,"meta":84},[225],"http:\u002F\u002Flocalhost:3000\u002Fr\u002Fcopy.json\n",[17,268,266],{"__ignoreMap":84},[10,270,271],{},"再到另一个已经初始化 shadcn-vue 的 Vue 或 Nuxt 项目中测试安装：",[78,273,276],{"className":274,"code":275,"language":187,"meta":84},[185],"pnpm dlx shadcn-vue@latest add http:\u002F\u002Flocalhost:3000\u002Fr\u002Fcopy.json\n",[17,277,275],{"__ignoreMap":84},[10,279,280,281,284],{},"检查 CLI 是否安装了 npm 依赖、Registry 依赖和组件文件，同时确认生成的导入路径符合目标项目的 ",[17,282,283],{"code":283},"components.json"," 配置。",[65,286,287],{"id":287},"发布与安装",[10,289,290,291,293],{},"部署项目时，需要确保 ",[17,292,220],{"code":220}," 中的文件会作为静态资源发布。部署完成后，先直接访问线上 JSON 地址，确认没有 404 或重定向到 HTML 页面。",[10,295,296],{},"以本文的域名为例，其他项目可以这样安装组件：",[78,298,301],{"className":299,"code":300,"language":187,"meta":84},[185],"pnpm dlx shadcn-vue@latest add https:\u002F\u002Fkit.prop.show\u002Fr\u002Fcopy.json\n",[17,302,300],{"__ignoreMap":84},[10,304,305],{},"至此，一个可以通过 shadcn-vue CLI 安装的自定义组件就发布完成了。",[65,307,308],{"id":308},"常见问题",[130,310,312],{"id":311},"构建后找不到-json-文件","构建后找不到 JSON 文件",[10,314,315,316,318,319,321,322,324,325,327],{},"确认命令是在包含 ",[17,317,61],{"code":61}," 的项目根目录运行，并检查 ",[17,320,127],{"code":127}," 是否真实存在。默认输出目录是 ",[17,323,220],{"code":220},"，自定义过 ",[17,326,235],{"code":235}," 时则以实际配置为准。",[130,329,331],{"id":330},"json-解析失败","JSON 解析失败",[10,333,334,336,337,340],{},[17,335,61],{"code":61}," 必须是严格 JSON，不能包含注释，也不能在数组或对象的最后一项后保留逗号。可以先让编辑器根据 ",[17,338,339],{"code":339},"$schema"," 检查格式，再运行构建命令。",[130,342,344],{"id":343},"本地可以访问部署后却是-404","本地可以访问，部署后却是 404",[10,346,347,349,350,352],{},[17,348,104],{"code":104}," 不会帮你配置静态资源路由。检查部署产物中是否包含 ",[17,351,220],{"code":220}," 下的文件，以及部署平台是否为站点配置了额外的基础路径。",[130,354,355],{"id":355},"安装成功后出现依赖或导入错误",[10,357,358,359,361,362,364],{},"检查 npm 包是否都写入 ",[17,360,142],{"code":142},"，shadcn-vue 组件或其他自定义组件是否都写入 ",[17,363,159],{"code":159},"。组件源码也不应依赖只存在于 Registry 项目内部、却没有一并发布的文件。",[65,366,367],{"id":367},"看看视频",[369,370],"video-embed",{"id":371,"type":372},"BV1TLq4BmEfd","bilibili",{"title":84,"searchDepth":374,"depth":374,"links":375},4,[376,382,383,384,385,391],{"id":67,"depth":377,"text":378,"children":379},2,"创建 registry.json",[380],{"id":132,"depth":381,"text":132},3,{"id":177,"depth":377,"text":178},{"id":259,"depth":377,"text":259},{"id":287,"depth":377,"text":287},{"id":308,"depth":377,"text":308,"children":386},[387,388,389,390],{"id":311,"depth":381,"text":312},{"id":330,"depth":381,"text":331},{"id":343,"depth":381,"text":344},{"id":355,"depth":381,"text":355},{"id":367,"depth":377,"text":367},null,[394],"经验分享","2026-08-02 10:50:03","将自己的 Vue 组件发布为 shadcn-vue Registry，并像官方组件一样通过 CLI 安装。",false,"md","https:\u002F\u002Fbitmc.uno\u002Fpicgo\u002Fpublish-your-own-shadcn-extension-with-cli.webp",{},true,"\u002Fposts\u002F2026\u002Fpublish-your-own-shadcn-extension-with-cli",{"text":404,"minutes":405,"time":406,"words":407},"6 min read",5.365,321900,1073,{"title":5,"description":396},{"loc":402},"posts\u002F2026\u002Fpublish-your-own-shadcn-extension-with-cli",[412,41,29],"Vue","2026-08-07 11:48:03","ylc4RDHDmIbp0NB11N_e8dj02DqmkYj2eFN8OSZ5I_Y",[416,421],{"title":417,"path":418,"stem":419,"date":420,"type":392,"children":-1},"手把手教你如何为 shadcn-vue 贡献代码","\u002Fposts\u002F2026\u002Fhow-to-contribute-to-shadcn-vue","posts\u002F2026\u002Fhow-to-contribute-to-shadcn-vue","2026-07-04 18:30:54",{"title":422,"path":423,"stem":424,"date":425,"type":392,"children":-1},"Nuxt 静态网站部署到 Cloudflare Pages","\u002Fposts\u002F2026\u002Fdeploy-nuxt-static-site-to-cloudflare-pages","posts\u002F2026\u002Fdeploy-nuxt-static-site-to-cloudflare-pages","2026-08-16 23:42:13",1789642584699]