You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 09:33:12