资讯详情

资讯详情

shadcn/ui Astro Monorepo 模板实战:用 pnpm Workspaces + Turborepo 搭建共享 React 组件库

shadcn/ui Astro Monorepo 模板实战用 pnpm Workspaces Turborepo 搭建共享 React 组件库【免费下载链接】uiA set of beautifully-designed, accessible components and a code distribution platform. Works with your favorite frameworks. Open Source. Open Code.项目地址: https://gitcode.com/GitHub_Trending/ui/ui本篇基于仓库中的 Astro Monorepo 模板说明文档完整解析 shadcn/ui 官方提供的 Astro React TypeScript Monorepo 模板apps/web中运行 Astro 应用packages/ui中以 workspace 包形式沉淀共享的 shadcn/ui 组件。读完后你可以掌握在 pnpm workspace 中配置workspace/ui跨包引用、理解两份components.json的差异、用 shadcn CLI 向共享包添加组件并在.astro文件中通过client:load正确挂载 React 组件的完整方案。模板定位应用与 UI 包分层模板的核心设计是把“会变化的界面逻辑”和“可复用的 UI 组件”拆开目录角色说明apps/webAstro 应用页面、布局依赖workspace/ui消费共享组件packages/ui共享 UI 包workspace/ui存放 shadcn/ui 生成的组件、hooks、工具函数与全局样式根目录 templates/astro-monorepo/package.json 声明了模板的运行基线{ packageManager: pnpm10.33.4, engines: { node: 22.12.0 }, devDependencies: { prettier: ^3.8.3, prettier-plugin-astro: ^0.14.1, prettier-plugin-tailwindcss: ^0.8.0, turbo: ^2.9.18, typescript: ~6 } }即pnpm 10 Node ≥ 22.12 Turborepo 2.9 TypeScript ~6。apps/web/package.json 则给出了具体框架版本astro ^7、astrojs/react ^5、react/react-dom ^19.2.6、tailwindcss/vite ^4Tailwind v4并且以workspace/ui: workspace:*的方式声明对共享包的工作区依赖。pnpm workspace 与构建脚本白名单pnpm-workspace.yaml 把apps/*与packages/*纳入同一工作区packages: - apps/* - packages/* allowBuilds: esbuild: true sharp: true msw: falseallowBuilds字段用于控制依赖的安装后构建脚本模板放行esbuild、sharp禁用msw避免不需要的依赖在安装阶段执行任意脚本。Turborepo根目录的统一任务入口turbo.json 定义了根目录五个脚本build/dev/lint/format/typecheck见根 package.json背后的任务编排{ ui: tui, tasks: { build: { dependsOn: [^build], inputs: [$TURBO_DEFAULT$, .env*], outputs: [dist/**] }, lint: { dependsOn: [^lint] }, format: { dependsOn: [^format] }, typecheck: { dependsOn: [^typecheck] }, dev: { cache: false, persistent: true } } }几个关键点build声明了dependsOn: [^build]即先构建被依赖的上游包packages/ui再构建消费方apps/web并以dist/**作为缓存产物dev标记为persistent: true且关闭缓存保证pnpm dev能持续运行 Astro 开发服务器而不被 Turborepo 杀掉lint/format/typecheck同样按依赖拓扑排序两个包会各自执行本目录定义的对应脚本例如 apps/web/package.json 的typecheck是astro check而 packages/ui/package.json 的是tsc --noEmit。因此日常只需在仓库根目录执行pnpm dev/pnpm build/pnpm typecheck等命令Turborepo 负责分发到各子包。跨包引用的三层配置workspace/ui模板让apps/web能以“按文件路径”的方式引用packages/ui中的源码无需构建产物这一能力由三层配置共同支撑。1. 包级exports子路径映射packages/ui/package.json 的exports把包内子目录逐一暴露为子路径exports: { ./globals.css: ./src/styles/globals.css, ./lib/*: ./src/lib/*.ts, ./components/*: ./src/components/*.tsx, ./hooks/*: ./src/hooks/*.ts }这意味着import { Button } from workspace/ui/components/button会被 Node/Vite 直接解析到packages/ui/src/components/button.tsx源文件——组件是“源码直连”而非编译后的dist产物这也是该模板里packages/ui没有build脚本的原因。2. 应用侧 TypeScript 路径映射apps/web/tsconfig.json 在astro/tsconfigs/strict基础上补了两组pathscompilerOptions: { jsx: react-jsx, jsxImportSource: react, paths: { /*: [./src/*], workspace/ui/*: [../../packages/ui/src/*] } }workspace/ui/*映射到packages/ui/src/*后编辑器与类型检查可以直接跳转到共享包源码/*则是 Astro 侧的常规src别名。packages/ui/tsconfig.json 内部也做了对称配置workspace/ui/*: [./src/*]使包内自引用在类型层面一致。3. Tailwind v4 的source扫描范围Tailwind v4 是 CSS-first 配置无tailwind.config文件样式入口是 packages/ui/src/styles/globals.cssimport tailwindcss; source ../../../apps/**/*.{ts,tsx,astro}; source ../../../components/**/*.{ts,tsx}; source ../**/*.{ts,tsx};由于组件源码散落在两个包、多个目录里Tailwind 默认的单目录扫描不足以收集全部候选类名因此这里用source显式声明应用侧所有.ts/.tsx/.astro文件、包内components与包内全部 TS 源码都是扫描对象。缺了这几行跨包组件的类名很可能不会被生成。shadcn 配置两份components.json的分工模板中apps/web与packages/ui各有一份components.json它们都使用同一套参数语义但指向不同的落盘位置。应用侧把生成物路由到共享包apps/web/components.json{ $schema: https://ui.shadcn.com/schema.json, style: radix-nova, rsc: false, tsx: true, tailwind: { config: , css: ../../packages/ui/src/styles/globals.css, baseColor: neutral, cssVariables: true }, iconLibrary: lucide, aliases: { components: /components, hooks: /hooks, lib: /lib, utils: workspace/ui/lib/utils, ui: workspace/ui/components } }逐条看关键参数style: radix-nova组件视觉风格rsc: falseAstro 场景不存在 React Server Componentsshadcn 生成代码时不会添加use client指令——在 Astro 中组件是否水合由client:*指令决定见后文tailwind.css指向跨包路径../../packages/ui/src/styles/globals.css从apps/web执行 shadcn 命令时CLI 会去修改共享包里的全局样式而不是应用本地文件保证主题变量单一来源baseColor: neutralcssVariables: true基础色板为 neutral主题以 CSS 变量形式注入便于运行时换肤iconLibrary: lucide图标统一来自 lucidealiases中components/hooks/lib仍指向应用自身/...但utils与ui指向workspace/ui——生成的组件依赖cn等工具函数时会引用共享包组件本体则可落在应用内。共享包侧以包根为锚点的镜像配置packages/ui/components.json 与上表的主要差异只有tailwind.css本地相对路径src/styles/globals.css和aliasesaliases: { components: workspace/ui/components, utils: workspace/ui/lib/utils, hooks: workspace/ui/hooks, lib: workspace/ui/lib, ui: workspace/ui/components }也就是说若直接在packages/ui目录上下文中运行 shadcn 命令所有产物都会写入packages/ui内部且包内文件互相引用时也使用workspace/ui/...别名。两份配置互为镜像、锚点不同共同保证“无论在哪一层执行 CLI引用解析都收敛到同一套路径”。添加组件shadcn add 命令按照 README 的说明在仓库根目录执行npx shadcnlatest add button -c apps/web-c apps/web将命令上下文定位到apps/webCLI 读取该目录的 components.json 完成配置解析组件代码按其ui别名workspace/ui/components对应的exports映射最终写入packages/ui/src/components/成为整个工作区共享的组件。从当前仓库快照看packages/ui/src/components 目录尚为空hooks、lib亦同而 apps/web/src/pages/index.astro 已预置了对button组件的引用——模板预期的使用顺序即先执行上述add命令生成组件文件应用即可直接跑起来。在 Astro 中使用组件README 给出的最小用法是在.astro文件中直接导入并使用组件--- import { Button } from workspace/ui/components/button --- html langen head meta charsetutf-8 / meta nameviewport contentwidthdevice-width / titleAstro App/title /head body div classgrid h-screen place-items-center content-center ButtonButton/Button /div /body /html模板实际首页 index.astro 在此基础上展示了一个关键的 Astro 集成细节--- import workspace/ui/globals.css import { Button } from workspace/ui/components/button --- body ... Button client:load classNamemt-2Button/Button /body两点值得注意client:load指令shadcn/ui 组件大量依赖 Radix 原语与客户端交互折叠、弹出、焦点管理等。在 Astro 中不加client:*的 React 组件只渲染为静态 HTML加上client:load后 Astro 会在页面加载时水合该组件交互能力才真正生效。这正是components.json里rsc: false的另一层含义——在 Astro 里客户端行为的开关在模板指令而不是use client。样式全局导入一次首页与 main.astro 布局均通过import workspace/ui/globals.css引入全局样式它经由 packages/ui/package.json 的./globals.css导出解析到共享包内的 globals.cssTailwind 主题与source扫描规则随之生效。应用侧的 Vite 配置也很简洁astro.config.mjs 仅挂了两个插件tailwindcss/viteTailwind v4 的 Vite 集成与astrojs/reactReact 渲染集成import tailwindcss from tailwindcss/vite import { defineConfig } from astro/config import react from astrojs/react export default defineConfig({ vite: { plugins: [tailwindcss()] }, integrations: [react()], })关键文件速查文件职责pnpm-workspace.yaml工作区成员与依赖构建脚本白名单turbo.jsonbuild / dev / lint / format / typecheck 任务编排packages/ui/package.jsonworkspace/ui的exports子路径映射源码直连packages/ui/components.json包级 shadcn 配置产物落在包内packages/ui/src/styles/globals.cssTailwind v4 入口与source扫描范围apps/web/components.json应用级 shadcn 配置CSS 指向共享包apps/web/tsconfig.jsonworkspace/ui/*→packages/ui/src/*类型路径映射apps/web/astro.config.mjsTailwind vite 插件 React 集成apps/web/src/pages/index.astro组件用法示例client:load水合小结这个模板的精髓在于“单一样式源、单一组件源、多层别名收敛”Tailwind 主题只存在于packages/ui/src/styles/globals.cssshadcn 生成的组件通过exportspathssource三层配置被应用无缝引用Turborepo 则把多包项目的日常命令压缩为根目录一条指令。理解了 apps/web/components.json 与 packages/ui/components.json 的分工以及client:load在 Astro 中的水合作用就可以在此基础上持续向packages/ui添加组件并扩展到多个前端应用。【免费下载链接】uiA set of beautifully-designed, accessible components and a code distribution platform. Works with your favorite frameworks. Open Source. Open Code.项目地址: https://gitcode.com/GitHub_Trending/ui/ui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →