Kendi bilingual teknik blog sitemi geliştirirken MDX dosyalarıyla çok haşır neşir oldum. Başlangıçta her şeyi hızlıca çalışır hale getirme derdindeyken, zamanla MDX dosyalarının içindeki import sıralaması ve component konumlandırmasının ne kadar kritik olduğunu fark ettim. Karmaşıklaşan içerik ve artan component sayısı, hem okunabilirliği hem de bakım maliyetini ciddi şekilde etkilemeye başladı.
Bu sorun, sadece benim blogum için değil, Astro gibi modern statik site jeneratörleriyle MDX kullanan birçok projede de karşılaşılan bir durum. Bir süre sonra her bir MDX dosyasının içindeki kod bloğu, adeta küçük bir karmaşa adasına dönüşebiliyor. Ben de bu durumla başa çıkmak için bazı best practice’ler geliştirdim ve bunları burada paylaşmak istiyorum.
MDX Dosyalarında Düzenin Önemi: Neden Uğraşıyoruz?
MDX dosyaları, Markdown’ın esnekliği ile React (veya başka bir JSX uyumlu framework) component’lerinin gücünü birleştirdiği için harika bir araç. Ancak bu güç, kontrolsüz kullanıldığında hızla bir baş ağrısına dönüşebilir. Benim deneyimimde, özellikle blog yazıları gibi sık güncellenen içeriklerde, MDX dosyalarının içindeki düzen, genel proje sağlığı için kritik bir faktör haline geldi.
Bir component’in nereden geldiğini, ne işe yaradığını anlamak için dakikalarca yukarı aşağı kaydırmak zorunda kaldığınızda, o dosyanın bakımı da imkansızlaşıyor. Sistem tarafında systemd unit dosyalarını veya PostgreSQL konfigürasyonlarını düzenlerken gösterdiğim titizliği, zamanla MDX dosyaları için de göstermem gerektiğini anladım. Aksi takdirde, küçük bir component hatası, derleme sürelerini uzatabilir veya beklenmedik render sorunlarına yol açabilir.
Import Sırası: Bağımlılık Hiyerarşisi ve Okunabilirlik
MDX dosyalarındaki import beyanlarının sırası, dosyanın okunabilirliği ve bağımlılıkların yönetimi açısından oldukça önemli. Ben kendi blogumda ve diğer projelerimde belirli bir hiyerarşi izliyorum. Bu hiyerarşi, bir component’in veya modülün nereden geldiğini hızlıca anlamamı sağlıyor.
Genel kuralım şu şekilde:
- Standard Library/Node.js Modülleri: Eğer varsa, en üste bunlar gelir.
- Üçüncü Parti Kütüphaneler: Projenin
package.jsondosyasında tanımlı olan harici kütüphaneler. - Yerel Component’ler (Genel): Projenin
componentsdizininden veya kök dizininden gelen, birçok farklı yerde kullanılan genel component’ler. - Yerel Component’ler (Özel): Mevcut MDX dosyasının bulunduğu dizine daha yakın, sadece belirli bir bölüm veya konu için kullanılan component’ler.
Bu sıralama, import bloğuna baktığımda hangi bağımlılığın ne kadar “uzak” veya “özel” olduğunu anında görmemi sağlıyor. Böylece bir hata durumunda, sorunun kaynağını (kendi kodum mu, üçüncü parti mi, yoksa bir layout component’i mi) daha kolay tahmin edebiliyorum.
---
title: "MDX Import Düzeni"
---
import { Fragment } from 'react'; // React, standard kütüphane gibi davranır
import { marked } from 'marked'; // Üçüncü parti kütüphane (örneğin syntax highlighting için)
import Callout from '../../../components/mdx/Callout.astro'; // Genel, reusable component
import FeatureCard from '../components/FeatureCard.astro'; // Yerel, bu konuya özel component
import type { Post } from '../types'; // Type import'ları, genellikle en alta
Yukarıdaki örnekte, import’ların mantıksal olarak gruplandığını ve okunabilirliği artırdığını görebilirsiniz. Bu disiplin, özellikle çok sayıda MDX dosyasını yönettiğim bir yan ürünümde çok işime yaradı.
Global vs. Local Component Tanımlamaları
MDX’in gücü, doğrudan dosya içinde component tanımlamanıza da olanak sağlamasıdır. Ancak bu özellik, dikkatli kullanılmadığında karmaşaya yol açabilir. Benim yaklaşımım, bu konuda net sınırlar çizmek.
Ne zaman yerel (inline) component tanımlamalıyım?
- Çok basit, tek kullanımlık ve başka hiçbir yerde kullanılmayacak küçük UI elementleri.
- Sadece o MDX dosyasına özgü, karmaşık state veya logic içermeyen yapılar. Örneğin, metin içinde küçük bir vurgu veya özel bir simge.
Ne zaman dışarıdan import etmeliyim?
- Tekrar kullanılabilirliği yüksek, birden fazla MDX dosyasında veya bölümde kullanılacak component’ler (örneğin
Callout,CodeBlock,ImageWithCaption). - Karmaşık logic, state yönetimi veya API çağrıları içeren component’ler. Bunları ayrı bir
.astro,.jsxveya.tsxdosyasında tutmak, test edilebilirliği ve bakımı kolaylaştırır. - Global stillerle veya temalarla entegre olması gereken component’ler.
Component Konumlandırması: Nereye Ne Koymalı?
Import sırası kadar, component’leri MDX dosyasının içinde nereye yerleştirdiğimiz de önemli. Genellikle üç ana senaryo görüyorum:
- Layout veya Wrapper Component’leri: Bunlar genellikle tüm MDX içeriğini sarmalayan veya genel bir düzen sağlayan component’lerdir. Astro’da bu,
layoutfrontmatter özelliği ile de yönetilebilir. Eğer özel bir wrapper component’i doğrudan MDX içinde kullanıyorsam, bunu genellikle içeriğin en başına yerleştiririm. - İçerik İçi Component’ler: Blog yazısının akışı içinde kullanılan, metinle birlikte render edilen component’ler. Örneğin, bir kod bloğu, bir grafik veya bir
Calloutbileşeni. Bunlar, içeriğin ilgili bölümünde yer almalıdır. - Yardımcı Component’ler: Bazen bir MDX dosyasının sonuna, ana içerikle doğrudan ilişkisi olmayan ancak sayfanın alt kısmında gösterilmesi gereken (örneğin, “ilgili yazılar” veya “yorumlar” bölümü) component’ler ekleyebiliriz. Benzer şekilde, bazı küçük
scripttag’leri de buraya gelebilir.
Layout Bileşenleri ve MDX İlişkisi
Astro gibi framework’ler, MDX dosyalarıyla layout bileşenlerini birleştirme konusunda çok güçlü mekanizmalar sunar. Bu, MDX dosyalarının sadece içerik barındırmasını, genel sayfa düzeni ve header/footer gibi elementlerin ise merkezi bir yerden yönetilmesini sağlar.
Benim pratiğimde, her blog yazısı için özel bir BlogPostLayout.astro bileşeni kullanıyorum. Bu bileşen, frontmatter’daki title, description gibi verileri alarak sayfanın <head> etiketini düzenler, ana menüyü ve footer’ı render eder. MDX dosyasındaki içerik ise bu layout bileşeninin slot’una yerleşir.
---
layout: ../../layouts/BlogPostLayout.astro
title: "MDX Layout Best Practices: Import Sırası ve Component Konumu"
description: "MDX dosyalarını düzenlerken edindiğim tecrübelerimi paylaşıyorum."
category: "technology"
tags: ["MDX", "Astro"]
---
Bu benim blog yazımın ana içeriği. Layout component'i bu içeriği sarmalayacak.
BlogPostLayout.astro dosyasının basit bir yapısı şöyle olabilir:
---
import BaseLayout from './BaseLayout.astro'; // Genel, tüm sayfalar için temel layout
const { frontmatter } = Astro.props;
---
<BaseLayout title={frontmatter.title} description={frontmatter.description}>
<article class="prose dark:prose-invert max-w-none">
<h1>{frontmatter.title}</h1>
<p class="text-gray-500 text-sm">Yayınlanma Tarihi: {frontmatter.publishDate}</p>
<slot /> {/* MDX içeriği buraya render edilir */}
</article>
</BaseLayout>
Bu yaklaşım, MDX dosyalarının temiz kalmasını ve sadece içerik odaklı olmasını sağlar. Layout değişiklikleri için tek bir dosya üzerinde çalışmak, yüzlerce MDX dosyasında manuel düzenleme yapmaktan çok daha verimlidir. İçerik ile sunumu bu şekilde ayırmak, çok sayıda teknik dokümanın merkezi tek bir noktadan tutarlı bir görünüme kavuşmasını sağlar.
Performans ve Bakım Perspektifi: Daha Temiz Kod, Daha Hızlı Derleme
MDX dosyalarının düzeni, sadece okunabilirlik için değil, aynı zamanda projenin genel performansı ve bakım maliyeti için de doğrudan etkilidir. Ben bu konuyu ilk olarak, kendi blogumun build süreleri uzamaya başladığında ciddiye almaya başladım.
Karmaşık ve düzensiz import yapıları, modül çözümleyicilerin (module resolver) daha fazla iş yapmasına neden olabilir. Özellikle büyük projelerde, gereksiz veya döngüsel bağımlılıklar, Hot Module Replacement (HMR) performansını düşürebilir ve geliştirme sunucusunun yavaşlamasına yol açabilir. Bir build sürecinde “circular dependency detected” hatası görmek, genellikle kötü bir import yönetiminin sonucudur ve bu hatayı düzeltmek bazen saatler sürebilir.
Aynı şekilde, component’lerin mantıksal olarak gruplandırılması ve konumlandırılması, yeni bir özellik eklerken veya mevcut bir hatayı giderirken harcadığınız zamanı azaltır. Bir component’in yerini ve amacını anında bilmek, hem zihinsel yükü azaltır hem de geliştirme hızını artırır. Benim blogumda, bu düzenlemeleri yaptıktan sonra yeni bir Callout tipi veya özel bir Aside component’i eklemek belirgin şekilde hızlandı.
Kendi Yan Ürünümdeki Deneyimlerim ve Çıkarılan Dersler
Kendi yan ürünlerimden birinde, başlangıçta hızlı hareket etme dürtüsüyle MDX dosyalarının düzenine pek önem vermedim. Her yeni component’i veya yardımcı modülü, ihtiyacım olan MDX dosyasının en tepesine, diğer import’ların arasına gelişigüzel ekledim. İlk başta sorun yoktu, çünkü proje küçüktü.
Ancak proje büyüdükçe ve içerik sayısı arttıkça, bu yaklaşımın sürdürülemez olduğunu gördüm. Örneğin, global bir Image component’inin props’unu değiştirmem gerektiğinde, hangi MDX dosyalarının bu component’i kullandığını bulmak ve her birinde manuel değişiklik yapmak tam bir kabusa dönüştü. Aynı component’in farklı versiyonlarının farklı MDX dosyalarında tanımlandığını bile gördüm.
Bu kaos ortamında, standart bir yol izlemenin ne kadar hayati olduğunu anladım. Yaptığım ilk şey, tüm yeniden kullanılabilir component’leri merkezi bir src/components dizinine taşımak ve MDX dosyalarının içindeki import yollarını bu yeni yapıya göre güncellemek oldu. Ardından, yukarıda bahsettiğim import sıralaması kuralını katı bir şekilde uygulamaya başladım.
Artık bir MDX dosyasını açtığımda, saniyeler içinde hangi harici bağımlılıkların olduğunu, hangi yerel component’leri kullandığını ve genel layout’unun ne olduğunu anlayabiliyorum. Bu, bana hem zaman kazandırıyor hem de zihinsel olarak daha az yorulmamı sağlıyor.
Sonuç
MDX, modern web geliştirme dünyasında içerik oluşturma ve yönetme biçimimizi dönüştüren güçlü bir araç. Ancak her güçlü araç gibi, onun da doğru kullanılması gereken incelikleri var. import sıralamasından component konumlandırmasına, layout bileşenlerinin kullanımına kadar her detay, projenizin uzun vadeli sağlığını ve bakım maliyetini etkiler.
Benim pratiğimde edindiğim en önemli ders, MDX dosyalarını da “kod” olarak görmek ve onlara da diğer yazılım dosyalarına uyguladığımız disiplini uygulamak oldu. Başlangıçta biraz çaba gerektirse de, bu düzenlemeler uzun vadede size kat kat geri dönecektir. Sonuçta, temiz ve düzenli bir codebase, sadece geliştiriciler için değil, aynı zamanda son kullanıcı için de daha kararlı ve performanslı bir ürün anlamına gelir. Bir sonraki MDX projenizde bu prensipleri uygulamayı düşünmenizi tavsiye ederim.