Turborepo ile Next.js ve Expo arasında kod paylaşımı
Yayın
Kısa cevap
Uygulamaları apps/ altına (Next.js web, Expo mobil), ortak kodu packages/ altına (tipler, doğrulama şemaları, API istemcisi, sabitler) koy, arayüz bileşenlerini platforma göre ayrı tut ve Turborepo'nun görevleri bağımlılık sırasıyla çalıştırıp önbelleğe almasına izin ver. Bileşenleri değil mantığı paylaş. Qrispy'de canlı web ve mobil uygulamalar için ortak paketli bir Turborepo monorepo kurdum.
Klasör yapısı
apps/
web/ # Next.js
mobile/ # Expo (React Native)
packages/
shared/ # tipler, zod şemaları, API istemcisi, sabitler
config/ # ortak tsconfig ve eslint ayarları
turbo.json
package.jsonNeyi paylaş, neyi paylaşma
- Paylaş: TypeScript tipleri, zod doğrulama şemaları, API istemcisi, iş kuralları, sabitler ve çeviri metinleri.
- Paylaşma: arayüz bileşenleri ve gezinme. Web'de DOM, mobilde React Native bileşenleri çalışır; zorla ortaklaştırmak ikisini de kötüleştirir.
Böylece web ve mobil aynı veri biçimini ve aynı doğrulama kurallarını kullanır, ama her platform kendi arayüzünü rahatça geliştirir.
Paketleri bağla
Ortak paketi her uygulamanın bağımlılığı olarak ekle. pnpm kullanıyorsan workspace protokolü yeterlidir.
{
"dependencies": {
"@acme/shared": "workspace:*"
}
}Ortak paketi derlenmiş çıktı yerine TypeScript kaynağı olarak paylaşıyorsan Next.js'e bunu transpilePackages ile söylemen gerekir. Expo'nun güncel sürümleri Metro'yu monorepo için kendiliğinden ayarlar; eski sürümlerde metro.config.js içinde watchFolders tanımlamak gerekebilir.
// apps/web/next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
transpilePackages: ["@acme/shared"],
};
export default nextConfig;turbo.json
Turborepo, bir paketin derlemesini onu kullanan uygulamalardan önce çalıştırır ve değişmeyen işleri önbellekten verir.
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"lint": {},
"dev": { "cache": false, "persistent": true }
}
}Dikkat edilecek yerler
- React sürümü: React Native belirli bir React sürümüne bağlıdır. Monorepo'da tek bir React sürümü kaldığından emin ol, yoksa tuhaf hatalar alırsın.
- Ortam değişkenleri uygulamaya özeldir. Ortak pakete uygulama sırlarını koyma.
- TypeScript ve eslint ayarlarını packages/config içinde tut ve uygulamalardan genişlet.
Sık sorulanlar
- Web ve mobil arasında arayüz bileşenlerini paylaşabilir miyim?
- Mümkün ama çoğu ekip için değmez. Tipleri, doğrulamayı, API istemcisini ve iş kurallarını paylaşmak daha az sürtünmeyle en büyük kazancı verir.
- Turborepo yerine pnpm workspaces yetmez mi?
- Workspaces paketleri bağlar. Turborepo üstüne görev sıralaması ve önbellek ekler; birden çok uygulama ve paket olduğunda derleme süresini ciddi azaltır.
- Next.js ortak paketi neden derlemiyor?
- Paketi TypeScript kaynağı olarak paylaşıyorsan next.config içinde transpilePackages listesine eklemen gerekir.
Bu konuda çalışıyorum
Yazan: Mert Yılmaz, freelance fullstack geliştirici.