W rozleglej infrastrukturze Metropolii Quantum 2150, gdzie dziesiaki mikroserwisow i aplikacji frontendowych wspolpracuja ze soba, potrzebujesz narzedzia do zarzadzania kodem na wielka skale. Turborepo to system budowania dla monorepo, ktory dziala z Next.js jak precyzyjny kwantowy procesor - szybko, wydajnie i niezawodnie.
Monorepo to strategia przechowywania wielu projektow w jednym repozytorium. Dla ekosystemu Next.js daje to ogromne korzysci:
1# Utworz nowe monorepo z Turborepo
2npx create-turbo@latest quantum-monorepo
3
4# Lub dodaj Turborepo do istniejacego projektu
5npm install turbo --save-dev1quantum-monorepo/
2 apps/
3 web/ # Glowna aplikacja Next.js
4 package.json
5 next.config.js
6 admin/ # Panel admina Next.js
7 package.json
8 next.config.js
9 docs/ # Dokumentacja Next.js
10 package.json
11
12 packages/
13 ui/ # Wspoldzielone komponenty React
14 package.json
15 src/
16 Button.tsx
17 Card.tsx
18 index.ts
19 config-eslint/ # Wspoldzielona konfiguracja ESLint
20 package.json
21 config-typescript/ # Wspoldzielona konfiguracja TypeScript
22 package.json
23 types/ # Wspoldzielone interfejsy TypeScript
24 package.json
25 src/
26 user.ts
27 product.ts
28
29 turbo.json # Konfiguracja Turborepo
30 package.json # Root package.json1{
2 "$schema": "https://turbo.build/schema.json",
3 "globalDependencies": ["**/.env.*local"],
4 "pipeline": {
5 "build": {
6 "dependsOn": ["^build"],
7 "outputs": [".next/**", "!.next/cache/**", "dist/**"]
8 },
9 "lint": {
10 "dependsOn": ["^build"]
11 },
12 "dev": {
13 "cache": false,
14 "persistent": true
15 },
16 "test": {
17 "dependsOn": ["^build"]
18 },
19 "type-check": {
20 "dependsOn": ["^build"]
21 }
22 }
23}Kluczowe elementy konfiguracji:
dependsOn: ["^build"] - buduj zaleznosci zanim zbudujesz pakietoutputs - co cachowac (foldery wynikowe)cache: false - dev server nie powinien byc cachowanypersistent: true - procesy dlugotrwale (dev server)1{
2 "name": "quantum-monorepo",
3 "private": true,
4 "workspaces": ["apps/*", "packages/*"],
5 "scripts": {
6 "build": "turbo build",
7 "dev": "turbo dev",
8 "lint": "turbo lint",
9 "test": "turbo test",
10 "type-check": "turbo type-check"
11 },
12 "devDependencies": {
13 "turbo": "^2.0.0"
14 }
15}1// packages/ui/package.json
2{
3 "name": "@quantum/ui",
4 "version": "0.1.0",
5 "main": "./src/index.ts",
6 "types": "./src/index.ts",
7 "dependencies": {
8 "react": "^18.3.0"
9 },
10 "devDependencies": {
11 "@quantum/config-typescript": "workspace:*",
12 "typescript": "^5.5.0"
13 }
14}1// packages/ui/src/Button.tsx
2import React from 'react';
3
4interface ButtonProps {
5 children: React.ReactNode;
6 variant?: 'primary' | 'secondary' | 'danger';
7 onClick?: () => void;
8 disabled?: boolean;
9}
10
11export function Button({ children, variant = 'primary', onClick, disabled }: ButtonProps) {
12 const styles = {
13 primary: { background: '#7c4dff', color: '#fff' },
14 secondary: { background: '#64ffda', color: '#000' },
15 danger: { background: '#f44336', color: '#fff' },
16 };
17
18 return (
19 <button
20 onClick={onClick}
21 disabled={disabled}
22 style={{
23 ...styles[variant],
24 padding: '10px 24px',
25 borderRadius: '8px',
26 border: 'none',
27 cursor: disabled ? 'not-allowed' : 'pointer',
28 opacity: disabled ? 0.5 : 1,
29 }}
30 >
31 {children}
32 </button>
33 );
34}1// packages/ui/src/index.ts
2export { Button } from './Button';
3export { Card } from './Card';1// packages/types/src/user.ts
2export interface User {
3 id: string;
4 email: string;
5 name: string;
6 role: 'admin' | 'user' | 'moderator';
7 createdAt: string;
8}1// packages/types/src/index.ts
2export * from './user';
3export * from './product';Aby uzyc wspoldzielonego pakietu w aplikacji Next.js:
1// apps/web/package.json
2{
3 "name": "@quantum/web",
4 "dependencies": {
5 "@quantum/ui": "workspace:*",
6 "@quantum/types": "workspace:*",
7 "next": "^14.2.0",
8 "react": "^18.3.0"
9 },
10 "devDependencies": {
11 "@quantum/config-typescript": "workspace:*",
12 "@quantum/config-eslint": "workspace:*"
13 }
14}Uzycie w kodzie aplikacji:
1// apps/web/app/page.tsx
2import { Button, Card } from '@quantum/ui';
3import type { Product } from '@quantum/types';
4
5export default async function HomePage() {
6 return (
7 <div>
8 <h1>Quantum Store</h1>
9 <Button variant="primary">Dodaj do koszyka</Button>
10 </div>
11 );
12}Turborepo uzywa inteligentnego systemu cache, ktory zapamietuje wyniki budowania i pomija niezmienione pakiety.
1# Pierwsze budowanie - wszystko od zera
2npx turbo build
3# Output: 5 tasks, 0 cached, 5 not cached
4# Czas: 45s
5
6# Drugie budowanie (bez zmian) - pelny cache
7npx turbo build
8# Output: 5 tasks, 5 cached, 0 not cached
9# Czas: 0.3s1# Polacz z Vercel Remote Cache
2npx turbo login
3npx turbo link
4
5# Teraz cache jest wspoldzielony miedzy developerami i CI1# Zbuduj tylko konkretna aplikacje
2npx turbo build --filter=@quantum/web
3
4# Zbuduj aplikacje i jej zaleznosci
5npx turbo build --filter=@quantum/web...
6
7# Zbuduj tylko to co sie zmienilo od ostatniego commita
8npx turbo build --filter=[HEAD^1]1// apps/web/next.config.js
2/** @type {import('next').NextConfig} */
3const nextConfig = {
4 transpilePackages: ['@quantum/ui'],
5 output: 'standalone',
6};
7
8module.exports = nextConfig;Opcja
transpilePackages mowi Next.js, zeby transpilowac kod z pakietow monorepo (domyslnie Next.js nie transpiluje node_modules).Vercel automatycznie buduje tylko zmienione aplikacje. Jesli zmienisz packages/ui, aplikacje zalezne od tego pakietu zostana przebudowane, a te niezalezne - pominiete.
Uzywaj scope (
@nazwa-organizacji/) dla wszystkich pakietow i aplikacji:1@quantum/ui
2@quantum/types
3@quantum/config-eslint
4@quantum/web
5@quantum/adminUzywaj
workspace:* dla wewnetrznych zaleznosci - nigdy nie hardcoduj wersji:1"@quantum/ui": "workspace:*"Kazda aplikacja ma wlasny plik
.env, a turbo.json deklaruje globalne zaleznosci od plikow srodowiskowych.Turborepo to potezne narzedzie do skalowania projektow Next.js w architekturze monorepo:
workspace:* dla wewnetrznych pakietowW Metropolii Quantum 2150, gdzie kazdy projekt rosnie i wymaga skalowania, Turborepo jest fundamentem architektury - pozwala zarzadzac dziesiatkami aplikacji i bibliotek z jednego miejsca.