如何在Turborepo单体仓库中跨Next.js应用共享UI与样式组件
在Turborepo单体仓库中共享Next.js应用的UI与样式组件
1. 创建共享包
在Turborepo根目录的packages文件夹下新建一个共享包(比如命名为@your-org/ui),这是跨应用共享资源的核心载体:
cd ~/Website mkdir packages/ui cd packages/ui pnpm init
修改该包的package.json,设置包名为@your-org/ui,并配置main(或module)字段指向编译后的入口文件;如果用TypeScript,还需添加types字段指定类型文件路径。
2. 定义全局样式变量与基础样式
在packages/ui内创建styles目录,编写全局样式变量文件variables.css:
:root { --font-family: 'Montserrat', sans-serif; --accent-color: #4F46E5; --bg-color: #f9fafb; }
再创建全局样式入口global.css,引入字体并设置基础全局样式:
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: var(--font-family); background-color: var(--bg-color); }
3. 封装可复用UI组件
在packages/ui/components目录下创建共享组件,比如按钮组件Button.tsx:
import React from 'react'; import '../styles/variables.css'; interface ButtonProps { children: React.ReactNode; variant?: 'primary' | 'secondary'; } export const Button = ({ children, variant = 'primary' }: ButtonProps) => { const buttonStyles = { padding: '8px 16px', borderRadius: '4px', border: 'none', cursor: 'pointer', fontFamily: 'var(--font-family)', backgroundColor: variant === 'primary' ? 'var(--accent-color)' : 'transparent', color: variant === 'primary' ? 'white' : 'var(--accent-color)', border: variant === 'secondary' ? '1px solid var(--accent-color)' : 'none' }; return <button style={buttonStyles}>{children}</button>; };
4. 在Next.js应用中接入共享包
在两个Next.js应用的package.json中添加共享包依赖:
{ "dependencies": { "@your-org/ui": "workspace:*" } }
执行pnpm install完成依赖安装。
引入全局样式
在每个Next.js应用的根布局文件中(App Router用app/layout.tsx,Pages Router用pages/_app.tsx)导入共享全局样式:
import '@your-org/ui/styles/global.css'; import type { Metadata } from 'next'; export const metadata: Metadata = { title: 'Your App', }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body>{children}</body> </html> ); }
使用共享组件
在应用的页面或组件中直接导入并使用共享组件:
import { Button } from '@your-org/ui/components/Button'; export default function Home() { return ( <div> <h1>Hello World</h1> <Button variant="primary">Primary Button</Button> <Button variant="secondary">Secondary Button</Button> </div> ); }
5. 配置Turborepo缓存(可选但推荐)
修改根目录的turbo.json,添加共享包的编译任务与应用的依赖关系,利用缓存提升构建效率:
{ "pipeline": { "@your-org/ui#build": { "outputs": ["dist/**"] }, "apps/website#build": { "dependsOn": ["@your-org/ui#build"], "outputs": [".next/**"] }, "apps/account#build": { "dependsOn": ["@your-org/ui#build"], "outputs": [".next/**"] } } }
如果使用TypeScript,需在共享包的tsconfig.json中设置outDir为dist,并确保应用的tsconfig.json能正确解析共享包的类型定义。
内容的提问来源于stack exchange,提问作者Matthew
相关产品推荐
相关产品推荐

