3
Arsitektur dan Struktur Direktori
Repository ini memisahkan kode aplikasi ke dalam beberapa direktori di bawah src/, dan setiap direktori memegang satu tanggung jawab. src/app memegang routing App Router, src/components memegang komponen presentasi yang dipakai ulang, src/lib memegang utilitas lintas komponen, src/constant memegang nilai konfigurasi, dan src/styles memegang CSS global. Aset statis tidak berada di src/, melainkan di public/ dan diakses lewat alias ~/.
Pembagian direktori
| Direktori | Tanggung jawab | Identifier nyata |
|---|---|---|
src/app | routing App Router, layout, error boundary, dan subdirektori src/app/api untuk endpoint | RootLayout, HomePage, Error |
src/app/components | halaman katalog komponen sebagai satu segmen route | ComponentsLayout |
src/components | komponen presentasi tanpa ketergantungan pada src/app | UnstyledLink, Button, NextImage, Skeleton |
src/lib | utilitas lintas komponen, logger, dan validasi environment | cn, logger, openGraph, isProd (lewat src/constant/env) |
src/constant | nilai konfigurasi dan flag environment | siteConfig, isProd, isLocal, showLogger |
src/styles | CSS global dan token warna | globals.css, colors.css |
public | aset statis yang dijangkau lewat alias ~/ | ~/svg/Logo.svg |
Isi src/constant hanya dua berkas. siteConfig menyimpan tiga nilai: title, description, dan url src/constant/config.ts:1-71. Berkas kedua menurunkan tiga flag dari process.env.NODE_ENV: isProd, isLocal, dan showLogger src/constant/env.ts:1-62.
src/lib menyimpan utils.ts, env.ts, helper.ts, logger.ts, dan og.ts. Inti utils.ts adalah cn, yang menggabungkan clsx dengan twMerge src/lib/utils.ts:1-73. Karena itu semua komponen presentasi bergantung pada satu fungsi ini, misalnya UnstyledLink yang mengimpor cn dari @/lib/utils src/components/links/UnstyledLink.tsx:44.
Arah dependensi
Arah impor berjalan satu arah: src/app boleh mengimpor src/components, src/lib, src/constant, dan src/styles; src/components hanya boleh mengimpor src/lib; dan src/lib boleh mengimpor src/constant. Tidak ada impor balik dari src/components ke src/app.
graph TD
app["src/app<br/>routing dan layout"] --> components["src/components<br/>komponen presentasi"]
app --> styles["src/styles<br/>globals.css dan colors.css"]
app --> constant["src/constant<br/>config.ts dan env.ts"]
app --> assets["public<br/>~/svg/Logo.svg"]
catalog["src/app/components<br/>katalog komponen"] --> components
catalog --> styles
components --> lib["src/lib<br/>utils.ts dan logger.ts"]
lib --> constant
libEnv["src/lib/env.ts<br/>validasi zod"] --> lib
style app fill:#2d7d46,color:#fff
style catalog fill:#2d7d46,color:#fff
style components fill:#8b5cf6,color:#fff
style lib fill:#f59e0b,color:#000
style libEnv fill:#f59e0b,color:#000
style constant fill:#f59e0b,color:#000
style styles fill:#336791,color:#fff
style assets fill:#336791,color:#fff
%% fig: Arah dependensi antar direktori di dalam src
%% desc: Panah menunjuk ke arah yang diimpor; src/app menjadi titik masuk, sementara src/components dan src/lib tidak pernah mengimpor balik ke src/app.src/app/layout.tsx menggambarkan pola paling lengkap: berkas ini mengimpor dua berkas CSS global dari @/styles/ dan mengambil siteConfig dari @/constant/config src/app/layout.tsx:4-85. RootLayout sendiri hanya merender <html> dan <body> yang membungkus children, tanpa provider tambahan src/app/layout.tsx:52-626.
Segmen /components mengikuti pola yang sama dengan skala lebih kecil. Layout segmennya mengimpor @/styles/colors.css src/app/components/layout.tsx:47, lalu halaman katalognya mengimpor sepuluh komponen dari @/components/buttons, @/components/links, dan dua komponen akar NextImage serta Skeleton src/app/components/page.tsx:14-238.
Satu-satunya impor dari src/lib ke src/constant terjadi di logger.ts, yang mengambil showLogger dari @/constant/env src/lib/logger.ts:1-29. Karena showLogger bernilai true hanya pada development atau ketika NEXT_PUBLIC_SHOW_LOGGER bernilai 'true', logger tidak menulis apa pun di production src/constant/env.ts:1-62.
Alias impor
Semua jalur panjang dihindari lewat dua alias di tsconfig.json. @/* dipetakan ke ./src/*, dan ~/* dipetakan ke ./public/* tsconfig.json:16-2010. Konsekuensinya, src/app/page.tsx dapat menulis import '@/lib/env'; untuk menjalankan validasi environment src/app/page.tsx:1-911, dan import Logo from '~/svg/Logo.svg'; untuk mengambil aset SVG dari public/ src/app/page.tsx:1812.
Batas client dan server
Halaman beranda ditandai 'use client' pada baris pertama, sehingga HomePage berjalan sebagai Client Component dan boleh memakai hook atau event handler src/app/page.tsx:1-911. Error boundary di src/app/error.tsx juga wajib berupa Client Component, karena menerima prop reset berupa fungsi src/app/error.tsx:1-613. Rincian keduanya ada di Halaman, Error Boundary, dan Endpoint API, sedangkan metadata yang diekspor layout.tsx dibahas di App Router, Layout, dan Metadata.
⚠️
src/lib/env.tsmemanggilenvVariables.parse(process.env)saat modul dimuat src/lib/env.ts:9-1314. Karenasrc/app/page.tsxmengimpor@/lib/envdi baris keempat src/app/page.tsx:1-911, nilaiNEXT_PUBLIC_SHOW_LOGGERyang bukan'true'atau'false'akan menggagalkan build maupun render halaman beranda. Jangan menambah variabel baru tanpa memperbaruischemazod di berkas itu.
Penempatan berkas juga menentukan siapa yang boleh memakainya. Komponen baru untuk UI masuk ke src/components, dan komponen itu hanya boleh bergantung pada src/lib. Nilai yang dibaca lintas halaman masuk ke src/constant. Aturan ini menjaga src/components tetap bebas dari route dan dari src/app, sehingga katalog di Katalog Komponen Pratinjau dapat merakit ulang komponen tanpa menyentuh routing.